I have no idea why these scripts echo "ex" instead of "zero". Seems straight forward but it's got me stumped. Any ideas?

PHP Code:

$ws=0;
echo $ws.','.($ws=='x'?'ex':'zero');
exit;

I would expect to see:
0,zero

But instead, it shows:
0,ex

Or...

PHP Code:

$ws=0;
$ws=($ws=='x'?'ex':'zero');
echo $ws;
exit;

I would expect it to echo "zero", but it echos "ex"

Any ideas why this is? Incidentally, it doesn't matter what string I use (or even if I use $ws==0), it consistently displays "ex".

I appreciate any ideas.

Thanks.

01-11-2013, 05:29 PM

speghettiCode

At the moment, I'm the only one posting in this forum anyways so I'm not trying to bump this thread...but I discovered something about my question above that might be of interest in helping to answer it...

PHP Code:

$ws=(int)0;$ws=($ws=='x'?'ex':'zero');echo $ws;exit;

PHP Code:

$ws=0;$ws=in_array($ws, array('x'))?'ex':'zero';echo $ws;exit;

The above 2 code blocks result in "ex". but why??? very confused! I'm sure it's easy once explained.

PHP Code:

$ws=(string)0;$ws=($ws=='x'?'ex':'zero');echo $ws;exit;

The above code displays "zero". Alright '0' does not equal 'x'.

But why does (int)0 equal 'x' in the first script? I didn't think I'd have to type cast an integer when not using quotes and explicitly stating the value. So I'm confused as to the behavior of the first 4 code blocks I've posted here.

Any ideas would be helpful because it's holding back some validation I'm trying to run in my scripts.

Thank you for your help.

01-12-2013, 10:36 AM

firesnaker

The code

Code:

($ws=='x'?'ex':'zero')

is a shorthand code.

In the longer form, it is :

Code:

if ($ws == 'x') {
$ws = 'ex'
}
else
{
$ws = 'zero'
}

01-12-2013, 11:18 AM

speghettiCode

Hello firesnaker,

Thank you for your reply. I understand the shorthand.

My question, though, was why does 0=='x' evaluate to TRUE?

01-12-2013, 05:54 PM

NogDog

Because of PHP's loose typing, where it's casting 'x' to integer so that it can compare both expressions as the same type, and (int) 'x' will evaluate to 0. If you don't want that loose typing, then use the "===" (is identical to) operator, which checks for both same type and value, instead of the "==" operator.

Rhetorical questions:
Why does it cast 'x' to an integer (resulting in true) instead of casting 0 to a string (resulting in false)? For example, ('x'=='y') evaluates to false. So it's not casting each of those to int.

Actual question:
If I have two numbers I am comparing, for example, and I don't know if they are floats, ints, etc., is it common practice to type cast them in the expression as in below?

In your first example, anything that can be considered a zero (0, 0.0, "0", NULL, FALSE, "") will be cast to float as 0.0, so if $a is FALSE and $b is "", then they would both be cast to 0.0 and the comparison would be true -- which may or may not be what you want to happen. If you want to make sure you are comparing numbers, you might want to test each value with is_numeric() first, and if either test fails throw an exception or whatever other error-handling you want to do.

Or you could insist that those variables be floats (or whatever), and test them accordingly with is_float(), etc; But I don't think there's a one size fits all solution, since many times loose typing and type-juggling works fine.

If it becomes really critical, you could even create classes for specific types, which you could then pass into function parameters with type-hinting.