This question already has an answer here:
Saw this online in one PHP snippet here.
/**
* @param string $str subject of test for integerness
* @return bool true if argument is an integer string
*/
function intStr($str) {
return !!preg_match('/^\d+$/', $str);
}
Running this code snippet produces:
> var_dump( intStr("abc") );
bool(false)
> var_dump( intStr("123") );
bool(true)
Questions:
Is the dual exclamation mark a a valid operator, or is it just the same as a "not-not", which negates itself?
Also, why is this operator used in-conjunction with the preg_match
function?
</div>
preg_match returns 0 or 1 (or false on error) and this intStr function is meant to return a boolean value. A single !$x
first converts $x
to boolean, then negates. !!$x
just reverts this negation, so it is a shorter way to write (bool)$x
.
However, this saving of four characters results in loss of readability (and two unneccessary operations, but that's negligible), so it's not recommended.
It's clever code, but there is a rule in programming: Don't be clever
Running this simplified function:
function test($value) {
return !!$value;
}
Tests:
> var_dump( test(1) );
bool(true)
> var_dump( test(0) );
bool(false)
> var_dump( test('1') );
bool(true)
> var_dump( test('0') );
bool(false)
> var_dump( is_bool( test('abc') ) );
bool(true)
> var_dump( is_bool( test('0') ) );
bool(true)
Observations:
Checked output using is_bool
. Apparently it somehow casts/forces the output to a boolean.
Conclusion:
From the PHP manual,
preg_match()
returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.
I can conclude that this function forces the return value to be a boolean value, instead of the possibility of an integer value returned by preg_match
.
!!
is equal to not not
. That means that !!'a'
will cast the string 'a'
to a boolean, and return the inverse of that. So, !!preg_match
means not not preg_match
, so a valid preg_match.