/    Sign up×
Community /Pin to ProfileBookmark

What does the variable actually contain?

Hello,

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

[code=php]
$ws=0;
echo $ws.’,’.($ws==’x’?’ex’:’zero’);
exit;
[/code]

I would expect to see:
0,zero

But instead, it shows:
0,ex

Or…

[code=php]
$ws=0;
$ws=($ws==’x’?’ex’:’zero’);
echo $ws;
exit;
[/code]

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.

to post a comment
PHP

7 Comments(s)

Copy linkTweet thisAlerts:
@speghettiCodeauthorJan 11.2013 — 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...

[code=php]
$ws=(int)0;
$ws=($ws=='x'?'ex':'zero');
echo $ws;exit;
[/code]


[code=php]
$ws=0;
$ws=in_array($ws, array('x'))?'ex':'zero';
echo $ws;exit;
[/code]


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

[code=php]
$ws=(string)0;
$ws=($ws=='x'?'ex':'zero');
echo $ws;exit;
[/code]


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.
Copy linkTweet thisAlerts:
@firesnakerJan 12.2013 — The code ($ws=='x'?'ex':'zero')</URL> is a shorthand code.

In the longer form, it is :
<i>
</i>if ($ws == 'x') {
$ws = 'ex'
}
else
{
$ws = 'zero'
}
Copy linkTweet thisAlerts:
@speghettiCodeauthorJan 12.2013 — Hello firesnaker,

Thank you for your reply. I understand the shorthand.

My question, though, was why does 0=='x' evaluate to TRUE?
Copy linkTweet thisAlerts:
@NogDogJan 12.2013 — 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 [b](int) 'x'[/b] 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.
[code=php]
<?php
$result = (0 == 'x');
var_dump($result); // true
echo "<br />n";
$result = (0 === 'x');
var_dump($result); // false
echo "<br />n";
$result = (0 === '0');
var_dump($result); // false
echo "<br />n";
$result = (0 == '1x');
var_dump($result); // false ('1x' will cast to 1)
[/code]
Copy linkTweet thisAlerts:
@speghettiCodeauthorJan 13.2013 — Thanks for the explanation, NogDog!

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?

[code=php]
if((float)$a==(float)$b){
//...
}
[/code]


The above code may not evaluate the same as
[code=php]
if($a===$b){
//...
}
[/code]


because who knows what $a or $b will be cast to?
Copy linkTweet thisAlerts:
@NogDogJan 13.2013 — For info on all the type-juggling possibilities, see http://php.net/manual/en/types.comparisons.php

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.
[code=php]
<?php

abstract class Type
{
private $value;
public function __construct($value=null)
{
if($value !== null) {
$this->set($value);
}
}
public abstract function set($value);
public function get()
{
return $this->value;
}
}

class FloatType extends Type
{
public function set($value)
{
if( ! is_numeric($value)) {
throw new Exception ("'$value' is not numeric");
}
$this->value = (float)$value;
}
}

function foo(FloatType $bar)
{
$result = $bar->value . " is " . (is_float($bar->value) ? '' : 'not ') . "a float";
return $result;
}

// actually do something now:
$test = 1.234;
echo foo(new FloatType($test));
echo "<br />n";
$test2 = '12nope';
echo foo(new FloatType($test2)); // throws exception
[/code]

That's likely overkill for most applications, but something along that lines might be quite useful when you really need to keep your variable types in order.
Copy linkTweet thisAlerts:
@speghettiCodeauthorJan 13.2013 — That link is now bookmarked! Thank you for the thorough explanation and class example. I really appreciate it.
×

Success!

Help @speghettiCode spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 6.15,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @nearjob,
tipped: article
amount: 1000 SATS,

tipper: @meenaratha,
tipped: article
amount: 1000 SATS,

tipper: @meenaratha,
tipped: article
amount: 1000 SATS,
)...