Why does "echo !!!0" output as 1? - php

i couldn't understand why i am getting the output "1" from the below statement in PHP,
<?php echo !!!0;?>
please let me know the reason

The statement is parsed as !(!(!0)). ! is the logical negation operator. When applying it to any other type than a boolean (true/false), the operand is first cast to a boolean value (0, empty string, empty array, null, empty SimpleXML objects = false; everything else true).
Let's break the statement down:
!!!0 ==
!!!false ==
!!true ==
!false ==
true
Finally, echo true will output 1.

Because PHP "casts" the 0 to a boolean when doing a logic operation.
So !0 is 1
!1 is 0
!0 is 1

! is used to negate statements (post-evaluated).
0 evaluates to false => true (1) => false (0) => true (1)
! ! !
Why is a number cast to boolean?
This happens implicitly by using !, the exclamation mark expects yes true or no false and so the value next to it gets automatically cast to something that fits this condition (yes or no).
You can make similiar experiments using:
var_dump( !"hello world" );
// ...
Explicit casts are done by putting the type in brackets: (boolean)1 === true
Update for #user2864740:
<?php
var_dump(!0 === true); // bool(true)
var_dump(!(0) === true); // bool(true)
var_dump((!0) === true); // bool(true)
var_dump((boolean)1 === true); // bool(true)
var_dump((boolean)1); // bool(true)
Update after discussion:
echo true; prints 1. But this does not change a variable for example:
$x = true;
echo $x; // 1
var_dump($x); // bool(true)

Related

PHP compare boolean values

I want to compare strings in an multi dimensional PHP ARRAY
I ran the Debugger and it jumps into the if condition but in my opinion it should not.
$strEmpty = $this->areStringsEmpty($needle, $haystack[$i]); // FALSE after method call
$one=strcasecmp($haystack[$i][0],$needle[0]); // evaluates to 6 , which shoult be FALSE
$two=strcasecmp($haystack[$i][1], $needle[1]); //evaluates to 2 , which alse should be false
if (!$strEmpty && $one && $two) { // TRUE && FALSE && FALSE
return TRUE;
}
why is this so ?
I know i could check against 0 in the condition , but i am wondering why this isnt done automatically.
strcasecmp returns 0 when the string matches. To get a boolean true when the strings match, you can do this.
$one=(strcasecmp($haystack[$i][0],$needle[0]) === 0); //TRUE when === 0
$two=(strcasecmp($haystack[$i][1], $needle[1]) === 0); //TRUE when === 0
The thing is, strcasecmp returns numbers. So it'll be true if the return is greater or lower than 0.
Input:
$var1 = "Hello";
$var2 = "hello2";
if (strcasecmp($var1, $var2) == true) {
var_dump(strcasecmp($var1, $var2));
}
Output:
int(-1)
As you can see, it's -1, but it's true.
You could simply add braces around the strcasecmp.
$one = (strcasecmp($haystack[$i][0], $needle[0]) == 0);
$two = (strcasecmp($haystack[$i][1], $needle[1]) == 0);
This will give you true if it's equal, false if it's not.
Example

False converted to null automatically in my PHP

I'm new to PHP and I found in my code, when I pass a FALSE to a function. It converted to null immediately. I've read some articles knowing that False and null are equal. But I don't know when this conversion happens.
Below is my code
function equal($expected, $actual){
if($expected == $actual) { //... }
}
function foo(){
$signal = getSignal();
equal(FALSE, $signal->good); //...
}
You will need to use triple equal signs === for equality. For example
false == null; // true
false === null; // false
0 == false; // true
0 === false; // false
Check the docs on comparison operators
No, they are NOT converted. You can var_dump($variable) at any time to see both the type and the value of $variable any time. But there are a few things which evaluates to false with the == comparison operator. So in fact false == null will evaluate to true just as false == 0 or false == "0" in PHP. This is why the comparison operator === comes into the picture - using that instead of == in above example, all will evaluate to false instead of true.
For more information, see http://php.net/manual/en/language.operators.comparison.php

Php "" and 0 return same value

$page_now=array_search($id, $user_id);
if($page_now==""){return TURE;}
else{return FALSE}//include [0]index
I have an array_search, if it can't find the match it will return "",
However I have problem on [0] index
if the search index return 0 which is 1st one from array.
if statement $page_now=="" & $page_now==0 both are return TURE
Try this
$var=0;
if($var!=""){echo "have value in var";}else{echo "no value in var";}
I want it return have value even it is 0
This is a documented behavior:
http://php.net/array_search
http://php.net/manual/en/types.comparisons.php
http://www.php.net/manual/en/language.types.type-juggling.php
Warning
This function may return Boolean FALSE, but may also return a
non-Boolean value which evaluates to FALSE. Please read the section on
Booleans for more information. Use the === operator for testing the
return value of this function.
Also make sure you are aware about this:
strict
If the third parameter strict is set to TRUE then the
array_search() function will search for identical elements in the
haystack. This means it will also check the types of the needle in the
haystack, and objects must be the same instance.
You should use strict comparison operator === if you don't want to fall into dark abyss of PHP weak-types comparisons:
php > var_dump(0 == "0afca13435"); // oops, password's hash check went wrong :)
bool(true)
php > var_dump(0 == false);
bool(true)
BUT:
php > var_dump(false == "0afca13435");
bool(false)
// Uh, oh :) that's because int and string comparison will cast string to int,
// and in php string->int cast will return either 0 or any numeric prefix the
// string contain; bool and string comparison will cast string to bool, and
// numeric prefix is no longer an issue
----------
php > var_dump(false == "");
bool(true)
php > var_dump(0 == "");
bool(true)
// WTF! :)
And with strict:
php > var_dump(0 === "0afca13435");
bool(false)
// ahh, much better
The function array_search() returns false if it can't find the match. So you should use strict comparison operator === and compare it with false:
if($page_now===false) {
return true;
}
else {
return false;
}
try this (the empty checks if the variable is empty (""(empty string), 0, false, null etc ) is counted as empty (and will trigger this)
your code is now not checking if something is empty you only check if it isn't "" and null etc. will be triggered as not empty.
if(empty($page_now)){
return true;
}else{
return false;
}
if it is allowed to be 0 you can use this
if(empty($page_now) && $page_now != 0){
return true;
}else{
return false;
}

Is !$festive the same as $festive==FALSE?

I have a doubt with a few lines of PHP.
I have the following code:
// returns TRUE if a day is festive, FALSE otherwise
$festive = isFestive();
//
$workingDay = $d>0 && !$festive;
Is $workingDay = $d>0 && !$festive the same as writing $workingDay = $d>0 && $festive==FALSE; ?
Any help is appreciated.
Yes, it is.
It is different if you instead do: $festive === FALSE since in that case, values of $festive that are "falsy" will not return true, since they not exactly FALSE.
It's all about data types and how PHP will treat different values of non-boolean types as "false". Check out the follow snippet to illustrate this:
<?php
$test = false;
$test2 = null;
$test3 = 0;
$test4 = '';
$test5 = array();
var_dump($test == false);
var_dump($test2 == false);
var_dump($test3 == false);
var_dump($test4 == false);
var_dump($test5 == false);
var_dump($test === false);
var_dump($test2 === false);
var_dump($test3 === false);
var_dump($test4 === false);
var_dump($test5 === false);
And the resulting output (formatted):
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(false)
bool(false)
bool(false)
bool(false)
Any if() expression is evaluated to be either false or true. If expression is not explicitly Boolean, then it is converted to boolean and then evaluated. Here is how PHP converts certain types to boolean. In general, if value (numeric, non-boolean) is non zero, it is considered TRUE. See this document to find out more on how PHP evaluates expressions.
So in your case $d>0 evaluates to boolean depending on $d real value, while for !$festive the $festive is first converted to boolean and then negated (!, i.e. if $festive is numberic value 2, then it is converted to TRUE (non-zero) and then negated so the !$festive expression evaluates to FALSE.
Additional note: since your logical condition is AND (&&), if $d>0 is evaluated to false the !$festive will not be evaluated as due to Boole's algebra false && <anything> is always false.

PHP's variable type leniency

The most recent comment on PHP's in_array() help page (http://uk.php.net/manual/en/function.in-array.php#106319) states that some unusual results occur as a result of PHP's 'leniency on variable types', but gives no explanation as to why these results occur. In particular, I don't follow why these happen:
// Example array
$array = array(
'egg' => true,
'cheese' => false,
'hair' => 765,
'goblins' => null,
'ogres' => 'no ogres allowed in this array'
);
// Loose checking (this is the default, i.e. 3rd argument is false), return values are in comments
in_array(763, $array); // true
in_array('hhh', $array); // true
Or why the poster thought the following was strange behaviour
in_array('egg', $array); // true
in_array(array(), $array); // true
(surely 'egg' does occur in the array, and PHP doesn't care whether it's a key or value, and there is an array, and PHP doesn't care if it's empty or not?)
Can anyone give any pointers?
763 == true because true equals anything not 0, NULL or '', same thing for array because it is a value (not an object).
To circumvent this problem you should pass the third argument as TRUE to be STRICT and thus, is_rray will do a === which is a type equality so then
763 !== true
and neither will array() !== true
Internally, you can think of the basic in_array() call working like this:
function in_array($needle, $haystack, $strict = FALSE) {
foreach ($haystack as $key => $value) {
if ($strict === FALSE) {
if ($value == $needle) {
return($key);
}
} else {
if ($value === $needle) {
return($key);
}
}
return(FALSE);
}
note that it's using the == comparison operator - this one allows typecasting. So if your array contains a simple boolean TRUE value, then essentially EVERYTHING your search for with in_array will be found, and almost everything EXCEPT the following in PHP can be typecast as true:
'' == TRUE // false
0 == TRUE // false
FALSE == TRUE // false
array() == TRUE // false
'0' == TRUE // false
but:
'a' == TRUE // true
1 == TRUE // true
'1' == TRUE // true
3.1415926 = TRUE // true
etc...
This is why in_array has the optional 3rd parameter to force a strict comparison. It simply makes in_array do a === strict comparison, instead of ==.
Which means that
'a' === TRUE // FALSE
PHP treating arrays as primitive values is a constant source of pain as they can be very complex data structures, it doesn't make any sense. For example, if you assign array to something, and then modify the array, the original isn't modified, instead it is copied.
<?php
$arr = array(
"key" => NULL
);
var_dump( array() == NULL ); //True :(
var_dump( in_array( array(), $arr ) ); //True, wtf? It's because apparently array() == NULL
var_dump( in_array( new stdClass, $arr ) ); //False, thank god
?>
Also, 'egg' is not a value in the array, it's a key, so of course it's surprising that it would return true. This kind of behavior is not ok in any other language I know about, so it will trip over many people who don't know php quirks inside out.
Even a simple rule that an empty string is falsy, is violated in php:
if( "0" ) {
echo "hello"; //not executed
}
"0" is a non-empty string by any conceivable definition, yet it is a falsy value.

Categories