PHP Two Exclaimation Mark "!!" Operator with preg_match? [duplicate] - php

This question already has answers here:
Double not (!!) operator in PHP
(6 answers)
Closed 9 years ago.
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?

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

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

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.

Related

Why does php in_array return true for an unmatched string value? Is this a bug? [duplicate]

I have found some odd behaviour while I was using the PHP function in_array(). I have an array like this:
$arr = [TRUE, "some string", "something else"];
Now if I want to check if "test" is in the array it is clearly not, but in_array() still returns TRUE, why is that?
$result = in_array("test", $arr);
var_dump($result); //Output: bool(true)
The same thing happens when using array_search():
$result = array_search("test", $arr);
var_dump($result); //Output: int(0)
I thought maybe that the value TRUE in the array was automatically causing the function to return TRUE for every result without checking the rest of the array, but I couldn't find any documentation that would suggest that very odd functionality.
This behaviour of the function in_array() and array_search() is not a bug, but instead well documented behaviour.
Both functions have a 3rd optional parameter called $strict which by default is FALSE:
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
mixed array_search ( mixed $needle , array $haystack [, bool $strict = false ] )
Now what that means is that by default both functions use loosely(==) comparison to compare the values. So they only check if the values are the same after PHP type juggling and without checking the type. Because of that in your example TRUE == "any none emtpy string" evaluates to TRUE.
So by setting the 3rd parameter to TRUE while calling the function you say that PHP should use strict(===) comparison and it should check value AND type of the values while comparing.
See this as a reference: How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ?
You are right, the boolean can indeed cause this. Set the strict flag in the in_array function, this way also the type of the element is checked (basically the same as using ===):
if (in_array("username", $results, true)) // do something
if (in_array("password", $results, true)) // do something
if (in_array("birthday", $results, true)) // do something

What is wrong with the PHP function in_array(...)? [duplicate]

This question already has answers here:
PHP in_array() / array_search() odd behaviour
(2 answers)
Closed 6 years ago.
The PHP function in_array(...) "checks if a value exists in an array".
But I'm observing a very strange behavior on handling strings (PHP v7.0.3). This code
$needle = 'a';
$haystacks = [['a'], ['b'], [123], [0]];
foreach ($haystacks as $haystack) {
$needleIsInHaystack = in_array($needle, $haystack);
var_dump($needleIsInHaystack);
}
generates following output:
bool(true)
bool(false)
bool(false)
bool(true) <- WHAT?
The function returns true for every string $needle, if the $haystack contains an element with the value 0!
Is it really by design? Or is it a bug and should be reported?
If you do not set the third parameter of in_array to true, comparison is done using type coercion.
If the third parameter strict is set to TRUE then the in_array() function will also check the types of the needle in the haystack.
Under loose comparison rules, effectively 'a' is equal to 0 since (int)'a' == 0.

Why in_array function return TRUE when we are looking for an empty string? [duplicate]

This question already has answers here:
PHP in_array() / array_search() odd behaviour
(2 answers)
Closed 6 years ago.
Could someone explain to me why that is true?
in_array('', array(0,1,2));
Because, as said in the docs:
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
Searches haystack for needle using loose comparison unless strict is set.
... and '' == 0 is true in PHP. If you want to use strict comparison, just call in_array() with three params:
in_array('', array(0, 1, 2), true); // false
... so the types will be checked as well, and String '' won't have a chance to match against Numbers.
in_array by default performs loose comparison. Thus '' is equivalent to 0.
There is third argument (boolean) to in_array function which says if the matching is to be performed in STRICT way or not.
if you do in_array('', array(0,1,2), TRUE); then the result will be false.
Refer the documentation

Comparing 2 different values returns true [duplicate]

This question already has answers here:
Why does (0 == 'Hello') return true in PHP?
(5 answers)
Closed 8 years ago.
I came across this while playing with php
$test1 = '123abc';
$test2 = 123;
var_dump($test1); echo "<br />";
var_dump($test2); echo "<br />";
$test3 = ($test1 == $test2) ? True : False;
var_dump($test3);
This resulted in:
string(6) "123abc"
int(123)
bool(true)
Could someone explain why $test3 came out true?
using "===" would make that false but that would be due to comparing string to int.
Also notice if I force (string)$test2 it would give me the expected false, and forcing (int)$test1 returns the expected true;
Does this mean $test3 return true because PHP automatically converted $test1 into int before comparison?
Look at the details here:
a string' == 0 also evaluates to true because any string is converted
into an integer when compared with an integer. If PHP can't properly
convert the string then it is evaluated as 0. So 0 is equal to 0,
which equates as true.
Also, in the official PHP documentation:
To explicitly convert a value to integer, use either the (int) or
(integer) casts. However, in most cases the cast is not needed, since
a value will be automatically converted if an operator, function or
control structure requires an integer argument.

in_array() always returns TRUE [duplicate]

This question already has answers here:
PHP in_array() / array_search() odd behaviour
(2 answers)
Closed 6 years ago.
$arrValue = array('first', 'second');
$ret = in_array(0, $arrValue);
var_dump($ret);
var_dump($arrValue);
Above example gives following result:
bool(true)
array(2) {
[0]=> string(5) "first"
[1]=> string(6) "second"
}
Why in_array() matches needle 0 to any given haystack?
That's because the function uses a non-strict comparison. The string in the array is compared to integer 0. Some typecasting is happening with data loss, and both are regarded the same:
var_dump(0 == 'first'); // bool(true)
So solve this, you can use the third parameter and set it to true to request strict comparison.
$ret = in_array(0, $arrValue, true);
Keep in mind, through, that strict is really strict. In a strict comparison, 0 is not equal to "0".
Docs: http://nl3.php.net/in_array
Basically here 0 treats as false, so the search will occur like the function in_array search false between your array value. Make it(0) string to get different output.
As php a support strict or non-strict comparison so you need to pass a third value true it tell the to be strict because by default it is non-strict.

Categories