Why zero (0) and string are the same in PHP? - php

<?php
// your code goes here
if (0 == "asdf")
echo "same";
else
echo "not same";
Hello, Why this code prints "same", not "not same"? I'm little bit confused about this weird result. Is this a bug?
Execution Result: see http://ideone.com/wfWRlq

No, this is not a bug the string just get's converted to a int. It converts it from left to right until a non numeric value. So since there is a non numeric value right at the start it gets converted to 0.
For more information about String to int see the manual: http://php.net/manual/de/language.types.string.php#language.types.string.conversion
And a quote from there:
The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero).
So as an example to show that:
echo "5xyz" + 5; // 5 + 5 -> 10
//^
echo "xyz5" + 5; // 0 + 5 -> 5
//^
echo "x5z" + 5; // 0 + 5 -> 5
//^

You should use ===. Because that do convert type of value.

That's one of non-intuitive behaviors of comparisons in PHP. There's == operator for loose comparison, what checks only values of given variables and === operator for strict comparison, what checks also types of variables. PHP manual has dedicated page with comparisons tables.

Related

Arithmetic in the return statement cause unexpected behavior

I'm currently learning PHP from a HTML, CSS, and JS background and I came across some unexpected behavior that interested me. Consequently, I experimented with the following code.
Experiment 1:
It seems that when written the return statement is written like this, everything before the arithmetic is removed/not rendered.
Code:
<?php
function add($num, $num2) {
return $num."+".$num2." = ".$num + $num2."<br>";
}
echo add(10, 7) . add(20, 1);
?>
Outputs:
17<br>
21<br>
Experiment 2:
However, when I change the first variable/parameter from $num to $num2, it seems that every between the first variable and the + operator is removed.
Code:
<?php
function add($num, $num2) {
return $num2."+".$num2." = ".$num + $num2."<br>";
}
echo add(10, 7) . add(20, 1);
?>
Outputs:
14<br>
2<br>
Experiment 3:
After trying it in JS, I realized that putting brackets around the arithmetic equation would output the expected result.
Code:
<?php
function add($num, $num2) {
return $num."+".$num2." = ".($num + $num2)."<br>";
}
echo add(10, 7) . add(20, 1);
?>
Outputs:
10+7 = 17<br>
20+1 = 21<br>
(Also making a $sum variable would fix the problem)
Question:
My question is what causes the unexpected behavior by not putting the brackets around the equation?
The behavior you are seeing is the result of "type juggling".
Because PHP is not strictly-typed, a string can be interpreted as an integer when needed (or assumed to be needed by the interpreter), or vice versa. So the data type is converted, and if you're not careful can cause issues. In many other languages you would get an error if you treated a string like an integer or an integer like a string. JavaScript, for example, has String.parseInt() to explicitly change the type.
What the interpreter is doing is roughly the following, step-by-step:
$num - establish an integer with value 10
10."+" - concatenating an integer with a string
Convert the current output to a string (10 becomes "10"), and append a plus sign
Output is now "10+"
"10+".$num2 - concatenating a string with an integer
Convert the integer to a string and append it
Output is now "10+7"
"10+7"." = " - concatenating 2 strings
Output is now "10+7 = "
"10+7 = ".$num - concatenating a string with an integer
Convert the integer to a string and append it
Output is now "10+7 = 10
"10+7 = 10" + $num2 - arithmetic calculation between a string and an integer
Convert the string to an integer and add it to the next integer.
In this case, when PHP converts a string to an integer, it starts at the beginning of the string and returns all numerals until it hits the first non-number, so "10+7 = 10" pulls out the 10, then hits the + and stops looking for numbers.
Output is now 17;
17."<br>" - concatenation of an integer and a string
Convert the integer to a string and append the <br>
Output is now 17<br>.
For reference:
Documentation on type juggling: http://php.net/manual/en/language.types.type-juggling.php
How does PHP know that you don't want to take this $num."+".$num2." = ".$num and arithmetically add it to this $num2."<br>"? It doesn't, unless you use parentheses to cause the $num + $num2 to happen first.
In the first example:
$num."+".$num2." = ".$num
Equates to the string: 10+7=10, and then:
$num2
Equates to 7.
When you attempt to add them + the string 10+7=10 must be cast to an integer 10 and and when added to 7 gives you 17 then the string <br> is concatenated.
See PHP: String Conversion to Numbers
With parentheses:
$num."+".$num2." = ".($num + $num2)."<br>";
You get string 10+7= concatenated with 10+7 (17) concatenated with string <br>.

Mysqli Statement returning incorrectly

I am trying to return the data that is true from my database using this mysqli statement
$resulttwo = mysqli_query($link, "
SELECT
*
FROM
Events
WHERE
time >= '%$lasttime%'");
The variable "lasttime" is an float of a really high value. The numbers in the database are all below below this number. However, when I use this statement, it returns all rows in the database. I do not understand why using this comparison yields incorrect results. Is there something that I am missing?
'%$lasttime%' is a string, that equates to zero when used in a numeric comparison. time may be a string column, as you say, but gets successfully cast numeric when you use >=. if $lasttime equaled 12345 and $time equaled 54321, then the comparison is 54321 >= '%12345%' which equates to 54321 >= 0, as '%12345%' doesn't get converted to an int.
To test:
select '%12345%' = 0, '12345' = 0
returns TRUE (because that's a non-numeric string, whose value is 0) and FALSE (because that string can be converted to 12,345, and not equal to 0).
I have no idea why you want to use wildcards in this query.

comparing type string numeric

in php.net the following is written:
If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. These rules also apply to the switch statement. The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value
var_dump("10" == "1e1"); // 10 == 10 -> true
var_dump(100 == "1e2"); // 100 == 100 -> true
why in the first example it is evaluated as true but, the statement $num = (int)"1e1" ; is evaluated as 1 and not 10???
furthermore, why in the second example it is evaluated as true but the statement $num = (int)"1e2" ; is evaluated as 1 and not 100??
I am not sure why (int)'1E1' displays 1 (it probably ignores all letters and anything after), but what works perfectly for me is this:
echo '1E1'*1; //returns 10
String and string comparison: "10" is the same string representation as "1e1".
Int and string comparison: 100 as string is "100" or "1e2" and is the same representation as "1e2";
Casting string to int: (int) "1e1" => 1 as intval("1e1").
Casting is not the same as equality.
1e1 is double.
var_dump("10" == "1e1");
// 10 (converts to real type, not int) == 10 (converts to real type, not int) -> true
My attempt to convert the numeric string (float type) to integer:
(int)'1E1'
It turns 1 instead of 100.

PHP if statement fails to validate on "!== 0"

How can the below be possible:
$varnum = 4;
if( $varnum/4 - floor($varnum/4) !== 0){
echo 'foo';
}
This echoes 'foo' on my server running PHP 5.1.6. If i change the operator to == I get the same results.
I have no idea why, but could it possibly be because "==" is "equals" and "!==" is "Not identical"? How then would I make them identical? I guess in javaScript I would "parseInt", but there is no such thing in PHP, right?
The reason this fails is because in PHP, the floor function returns a float, despite the fact that the value is always a whole number. You can see this in the documentation here: http://php.net/manual/en/function.floor.php
You're doing a fixed type comparison of that float to an integer zero, so the result is false, regardless of whether the value is actually zero.
To fix this, either:
cast the output of floor to an integer - either intval(float(...)) or (int)float(..)
use != instead of !==.
use 0.0 instead of just 0 to compare against.
In case you're wondering why floor() would return a float rather than an integer, it's because the input is a float. The float data type has a larger possible range than integer, and thus it is possible to call floor() on a value that would be too big to hold in an integer. Therefore it would not be safe for the function to return an integer; it returns a float instead so that it can guarantee the result will be correct.
It may seem odd at first glance, but hopefully that explains the logic behind it for you.
What is it you are trying to accomplish? If you are trying to see if $varnum is divisible by four then use modulus, so...
$varnum = 4;
if ($varnum % 4 != 0) {
echo "foo - $varnum is divisible by 4";
}
You original post should use '!=' versus '!==', like this:
$varnum = 4;
if( $varnum/4 - floor($varnum/4) != 0){
echo 'foo';
}

unable to determine if a string is currently an integer or not

The following funciton drove me nuts. How on earth 100x could be equal to 100 and then 100x is reported as an integer?
For the life of me, I cannot figure it out.
You can copy and paste the whole thing and see it for yourself.
I'm missing a simple point somewhere here, help me out guys.
function blp_int($val) {
$orgval = $val;
$num = (int)$val;
echo "<li><font color=red>val: ". $val . " is being checked to see if it's an integer or not";
echo "<li><font color=red>orgval: ". $orgval ;
echo "<li><font color=red>num: ". $num ;
if ($orgval==$num) {
echo "<li><font color=red><b>YES IT IS! the [{$orgval}] is equal to [{$num}]</b>";
return true;
}
return false;
}
if (blp_int("100"))
{
echo "<h1>100 is an integer!</h1>";
}
else
{
echo "<h1>100 is NOT an integer!</h1>";
}
if (blp_int("100x"))
{
echo "<h1>100x is an integer!</h1>";
}
else
{
echo "<h1>100x is NOT an integer!</h1>";
}
the above code, when run returns the following;
val: 100 is being checked to see if it's an integer or not
orgval: 100
num: 100
YES IT IS. the [100] is equal to [100]
100 is an integer!
val: 100x is being checked to see if it's an integer or not
orgval: 100x
num: 100
YES IT IS. the [100x] is equal to [100]
100x is an integer!
I can remedy the situation by adding the following bits
if (!is_numeric($val))
{
return false;
}
to the top of the blp_int function right off the bat but,.. I'm still super curious to find out why on earth php thinks 100x=100 are equals.
As you can see in this example, casting 100x as an integer converts it to 100. Since you are not using strict comparison, '100x' == 100 is true. PHP removes the x from it to make just 100.
You could use strict comparison (which also compares the types), such that '100x' === 100 would return false. Using it, any time a string was compared to an integer, it would return false.
As per your edit: is_numeric may not be the most reliable, as it will return true for numbers formatted as a string, such as '100'. If you want the number to be an integer (and never a string), you could use is_integer instead. I'm not quite sure what exactly you're doing, but i thought I'd add this note.
I think you should use three equal signs in your IF:
if ($orgval===$num) {
Otherwise PHP casts the value 100x to 100 and 100=100.
Documentation: Comparison Operators
What kind of check do you want to do? There are a few ways you could go about it:
if (preg_match('!^[0-9]+$!', $input))
if (intval($input) == $input)
if (intval($input) === $input)
if ('x'.intval($input) === 'x'.$input)
It depends on how closely you want to check if it's an integer. Does it matter if you need to trim() it first?
Either cast it to an int or try http://php.net/manual/en/function.ctype-digit.php. You also need === in your if.

Categories