1

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"?

3
  • 2
    This is false. An empty string, the string "0" and NULL. If the string is numerical, it will contain that value when cast to INT, otherwise it will be cast to 0 or FALSE. Commented Dec 2, 2015 at 13:54
  • Check this link for type comparisons : php.net/manual/en/types.comparisons.php Commented Dec 2, 2015 at 14:08
  • Thanks for your input guys. I think Niet the Dark Absol's answer below explains it. There's no intermediate step of converting to an int when the condition does the type juggling: it goes straight from a string to a bool. Commented Dec 2, 2015 at 14:11

3 Answers 3

5

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)

Sign up to request clarification or add additional context in comments.

1 Comment

so the condition type juggling mechanism converts the string directly to a bool with no intermediate step of converting to an int? That makes sense, and does explain why the condition expression evaluates to true
1

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.

2 Comments

Can I ask as to how this answers the question at hand?
@SamSwift웃: Quote henrywright 'why doesn't my condition print "I will not be printed"?' - because only the strings '', '0' and NULL is converted to FALSE. CHange the string and you will get "I will not be printed"
0

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

1 Comment

@Uchiha, I did, but what I am trying to do is show what happens when a string is type casted to an int where it is of string value (a-z A-Z)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.