-3

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:

  1. Is the dual exclamation mark a a valid operator, or is it just the same as a "not-not", which negates itself?

  2. Also, why is this operator used in-conjunction with the preg_match function?

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260

3 Answers3

3

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

Fabian Schmengler
  • 24,155
  • 9
  • 79
  • 111
0

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.

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
0

!! 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.

Berry Langerak
  • 18,561
  • 4
  • 45
  • 58