henrywright
henrywright

Reputation: 10250

PHP: Understanding string type juggling

If I set $var to a string in PHP, that variable will evaluate to true in any conditions:

$var = "foo";
if ( $var ) {
    echo 'I will be printed';
} else {
    echo 'I will not be printed';
}

I understand that my condition above automatically does type juggling so that $var is converted in a bool.

Now, if I cast $var to an integer, I get 0:

var_dump( (int)$var ); // int(0)

0 is a falsy value which becomes false when converted to a bool:

$zero = 0;
var_dump( (bool)$zero ); // bool(false)

Considering the above, why doesn't my condition print "I will not be printed"?

Upvotes: 1

Views: 578

Answers (3)

Hasse Björk
Hasse Björk

Reputation: 1601

Here is a simple test of truth:

$s = array( // bool  (int)cast
    '',     // FALSE int=0
    'Test', // TRUE  int=0
    '0.0',  // TRUE  int=0
    '124',  // TRUE  int=124
    '000',  // TRUE  int=0
    '0',    // FALSE int=0
    NULL    // FALSE int=0
);


foreach( $s as $var )
    echo $var . ' // ' 
        . ( $var ? 'TRUE' : 'FALSE' ) . ' '
        . 'int=' . (int)$var . PHP_EOL;

In case of a string casting to bool, FALSE is an empty string, NULL and the value '0'. Everything else is TRUE. See the manual on false.

In your case, $var is a string "foo", which is not being converted to FALSE since it is neither NULL, "0" or "", therefore you will not get 'I will not be printed'.

If you cast it to an INT, everything is 0 except a pure numerical value.

Upvotes: 1

anon
anon

Reputation:

You will not get the else echo done, as a string that is not empty evaluates to true when used in an if, i.e.:

$foo = "Hello";
if ($foo)
    print "True"; //This will print as a string is true if not empty
else 
    print "False"; //Doesn't print as string is not empty

Try this:

$foo = "Hello";
if ((int)$foo)
    print "True";
else
    print "False"; //Will print as the string evaluates to 0 (false) as it is not an integer

Upvotes: 0

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324810

Type juggling isn't lossless. It comes with potential loss of data.

For instance...

var_dump( strval(intval("foo"))); // string(1) "0"

But if you were to write...

if( "foo" == "0") // non-strict comparison intended

You would surely not expect it to run! And indeed it doesn't.

So because type changes come with data loss, you can't expect conversions to be equivalent. In other words, boolval(intval($var)) and boolval($var) need not be the same.

If you want to be strict in your comparisons, use something like this:

if( is_string($var) && $var !== "") // is not the empty string

(Arguably !== is redundant and != works fine, but arguably this whole condition is overkill)

Upvotes: 5

Related Questions