why result of this Comparing is true - php

in this simple PHP code
why php parser return true?
$text="51.406ABC917";
$floatval = floatval($text);//51.406
if($floatval==$text){
$result_compare = true;//php parser return true
}else{
$result_compare = false;
}

It's about Type Juggling and PHP type comparison tables, and Comparison Operators. Just check it.
Type of Operand 1:string, resource or number
Type of Operand 2: string, resource or number
Translate strings and resources to numbers, usual math.
You could avoid convertion to float by adding typecasting to string.
if((string)$floatval==$text){
$result_compare = true;
}else{
$result_compare = false; //php parser return false
}

== will compare the data ,use === to compare data and datatype

$floatval==$text
in the above comparison you are comparing a float value with a string
try with === instead of ==

Look here . You should never compare floats for equality.
You need use the epsilon technique.
For example:
if (abs($forstFloat - $secondFloat) < epsilon) {
echo 'they are equal!!'
}
where epsilon is constant representing a very small number.

$a == $b Equal TRUE if $a is equal to $b after type juggling.
$a === $b Identical TRUE if $a is equal to $b, and they are of the same type.
Take this as example
<?php
var_dump(0 == "a"); // 0 == 0 -> true
var_dump("1" == "01"); // 1 == 1 -> true
var_dump("10" == "1e1"); // 10 == 10 -> true
var_dump(100 == "1e2"); // 100 == 100 -> true
switch ("a") {
case 0:
echo "0";
break;
case "a": // never reached because "a" is already matched with 0
echo "a";
break;
}
?>
Reference

Try this,
$text="51.406ABC917";
$floatval = floatval($text);//51.406
if($floatval===$text){
$result_compare = 'true';//php parser return true
}else{
$result_compare = 'failed';
}
LOGIC:
$a == $b Equal TRUE if $a is equal to $b after type juggling.
$a === $b Identical TRUE if $a is equal to $b, and they are of the same type.
Ref: http://www.php.net/manual/en/language.operators.comparison.php

Before comparison $text is converted to a float , with same result as floatval(),
then you compare $floatval==$text, so result is pretty predictable - TRUE
It's normal, when you compare variables from 2 different types, first them to be converted to closest same type.
I would suggest, when comparing float, use similar construct
if ( abs($floatval - floatval($text)) < 0.001 ) {..}
compare difference between 2 floats, instead them. Cause if u have 2 numbers, 45 and 45.00001 , php will think they differ.
What do you wanna accomplish ? Why you think this result is wrong ?

try this:
<?php
$text="51.406ABC917";
$floatval = floatval($text);//51.406
if(strval($floatval)==$text){
$result_compare = true;//php parser return true
}else{
$result_compare = false;
}
?>

If first part of string is numbers, it will be converted to numbers otherwise it will be zero (0). Yes, to compare value and type of variable, use === instead of ==.
But in your case, you already convert string to float by floatval($text); then === same as ==.
The problem is how php convert string to number by floatval($text);
This is how php convert string to numbers:
<?php
$foo = 1 + "10.5"; // $foo is float (11.5)
$foo = 1 + "-1.3e3"; // $foo is float (-1299)
$foo = 1 + "bob-1.3e3"; // $foo is integer (1)
$foo = 1 + "bob3"; // $foo is integer (1)
$foo = 1 + "10 Small Pigs"; // $foo is integer (11)
$foo = 4 + "10.2 Little Piggies"; // $foo is float (14.2)
$foo = "10.0 pigs " + 1; // $foo is float (11)
$foo = "10.0 pigs " + 1.0; // $foo is float (11)
?>
Full document here: http://www.php.net/manual/en/language.types.string.php#language.types.string.conversion

Related

Why PHP condition getting true even if i am checking equal to

<?php
$test = "-3,-13";
if ($test == -3) {
echo "yay";
} else {
echo "nay";
}
?>
why it always runs through if condition and not going in else condition? I am new to php so do not know what's going on here.
The string is converted into an integer "-3, 46, blala" -> -3 , then the condition is evaluated.
Use the === operator to avoid conversion.
Most of the time, you do not want to let php do the conversion in your place (security problem). Rather, the request is refused.
As PHP documentation says
Example Name Result
$a == $b Equal TRUE if $a is equal to $b after type juggling.
$a === $b Identical TRUE if $a is equal to $b, and they are of the same type.
When we compare a number with a string, the string is converted to a number and the comparison performed numerically.
var_dump(0 == "a"); // 0 == 0 -> true
var_dump("1" == "01"); // 1 == 1 -> true
https://www.php.net/manual/en/language.operators.comparison.php

PHP - need clarification on is_int() and while loop

I want to convert a decimal number to an integer by multiplying it by 10 until it gives me an integer.
Example:
0.2 should become 2 and
0.004 should become 4
Here is my function
function make_integer($num){
if (!is_int($num)){
$temp = $num;
while (!is_int($temp)){
$temp *= 10;
}
return $temp;
}
return $num;
}
I want
make_integer(0.2) => 2
Shouldn't the function stop when $temp becomes an integer?
The function seems to be going in an infinite loop.
Could someone tell me why this isn't working please?
Short answer
This will solve your problem
function make_integer($num){
if ((int)$num != $num){
$temp = $num;
while ((int)$temp != $temp){
$temp *= 10;
}
return $temp;
}
return $num;
}
Long Answer
The problem is that is_int does not test if your value is an integer or not. It will test if its type is an integer or not. So is_int($var) will do the same as if you ran gettype($var) == 'integer'.
Some basic tests:
is_int((int) 0.57); # returns true, because the type is an int.
is_int((float) 4); # returns false, because the type is a float
is_int(10 * 0.2); # returns false, because int*float will be typecasted to a float
To make your code work, and to test if a value is an integer, you should cast your variable to an integer and then test if it is still equal to the original variable, like this:
(int) $var == $var; # will return true if the value is int
To fix your code, substitute the !is_int($num) with (int) $num != $num and !is_int($temp) with (int) $temp != $temp, just like the code in the short answer above.
But, I can't resist to give an alternative solution to your problem. Personally, I would opt to use recursion for this problem. Like this:
function make_integer($num) {
return (int)$num == $num ? $num : make_integer($num * 10);
}
Or if you dislike the ternary operator:
function make_integer($num) {
if ((int)$num == $num)
return $num; # We're all done!
else
return make_integer($num * 10); # Try to increase by 10
}
Even longer answer
The type casting of php will take some time to learn. In general, PHP will allways try to type cast if it can. When you multiply an integer with a float, the result will be a float, even if it "looks" like an integer.
So try this code and pay special attention to the output:
$var = 0.03;
var_dump($var); # float(0.03)
var_dump(gettype($var)); # string(6) "double"
var_dump(is_int($var)); # bool(false)
Now, if you multiply by the integer 100, php will stick the float, as <float>*<int> multiplication allways will result in a float, regardless of the value.
$var *= 100; # (100 * 0.03)
var_dump($var); # float(3)
var_dump(gettype($var)); # string(6) "double"
var_dump(is_int($var)); # bool(false)
Note that the value is a natural number, but the type is still a float, and thus is_int will not return true.
To test if a actual value of a variable is indeed an integer, we will need to do our own little trick with manual typecasting.
$var = 2.33;
var_dump($var); # float(2.33)
$var = (int) $var;
var_dump($var); # int(2)
Note that when we tried to cast a float to an int the value changed. But if we try to cast a float that is an integer to an int, the value remains unaffected, only the type gets changed:
$var = 2.0;
var_dump($var); # float(2)
$var = (int) $var;
var_dump($var); # int(2)
And now, remember how <int>*<float> resulted in a float? PHP will work in the same way when you do comparisons. In php, "2.0" == 2 will be true because of this automatic typecasting. So when you do <int> == <float> what really happens is (float)<int> == <float>.
So what happens if we do (float)(int)0.3. First we typecast 0.3 to int(0), then we typecast back to float(0). Obviously, float(0) == float(0.3) will be false. But (float)(int)3.0 will be cast first to int(3) then to float(3), which was the same value we started with.
$var = 3.0;
var_dump($var); # float(3)
$var = (int) $var;
var_dump($var); # int(3)
$var = (float) $var;
var_dump($var); # float(3)
So if we do (int) 3.0 == 3.0, it will result in (float)(int) 3.0 == 3.0 which is true.
So the way to test if a value is integer is to do
(int)$var == $var
answer:
$i=0.0004 ;
gettype($i) == 'float'
$i*= 10;
gettype($i) == 'float'
float != int
to resolve your problem, change the logic test.
(int) $i == $i
This isn't the prettiest but it works.
function make_int($num){
//if it's not an int...
if(!is_int($num)){
//find out how many decimal places and store in a variable
$multiply = strlen(substr(strrchr($num, "."), 1));
//multiply the number by the power of the multiple.
$num *= (pow (10,$multiply));
return $num;
}
}
make_int(0.004);

php variables comparison == vs ===

this is code:
$s = 0;
$d = "dd";
if ($s == $d) {
var_dump($s);
die(var_dump($d));
}
result is:
int 0
string 'dd' (length=2)
Please explain why.
why ($s == $d) results as true?
Of course, if === is used it will results as false but why this situation requires ===?
Shouldn't it be returned false in both situations?
Because (int)$d equals with 0 and 0=0
you must use strict comparison === for different character tyes (string) with (int)
Your $d is automatically converted to (int) to have something to compare.
When you compare a number to a string, the string is first type juggled into a number. In this case, dd ends up being juggled into 0 which means that it equates to true (0==0).
When you change the code to:
<?php
$s = 1;
$d = "dd";
if ($s == $d)
{
var_dump($s);
die(var_dump($d));
}
?>
You will find that it doesn't pass the if statement at all.
You can more details by reading up on comparison operators and type juggling.
The string "dd" is converted to int, and thus 0.
Another example :
if ( "3kids" == 3 )
{
return true;
}
And yes, this returns true because "3kids" is converted to 3.
=== does NOT auto convert the items to the same type.
Also : 0 == false is correct, but 0 === false is not.
See : http://php.net/manual/en/language.types.type-juggling.php
The string will try to parsed into a number, returns 0 if it is not in right number format.
As seen in the php website :
http://php.net/manual/en/language.operators.comparison.php
var_dump(0 == "a"); // 0 == 0 -> true
In PHP, == should be pronounce "Probably Equals".
When comparing with ==, PHP will juggle the file-types to try and find a match.
A string with no numbers in it, is evaluated to 0 when evaluated as an int.
Therefore they're equals.

Operator precedence issue in Perl and PHP

PHP:
$a = 2;
$b = 3;
if($b=1 && $a=5)
{
$a++;
$b++;
}
echo $a.'-'.$b;
$a = 2;
$b = 3;
if($a=5 and $b=1)
{
$a++;
$b++;
}
echo $a.'-'.$b;
Output 6-16-2.I don't understand the 1 here.
Perl :
$a = 2;
$b = 3;
if($b=1 && $a=5)
{
$a++;
$b++;
}
print $a.'-'.$b;
$a = 2;
$b = 3;
if($a=5 and $b=1)
{
$a++;
$b++;
}
print $a.'-'.$b;
Output 6-66-2, I don't understand the second 6 here.
Anyone knows the reason?
Actually I know && has higher precedence than and,but I still has the doubt when knowing this before hand.
UPDATE
Now I understand the PHP one,what about the Perl one?
Regarding Perl:
Unlike PHP (but like Python, JavaScript, etc.) the boolean operators don't return a boolean value but the value that made the expression true (or the last value) determines the final result of the expression† (source).
$b=1 && $a=5
is evaluated as
$b = (1 && $a=5) // same as in PHP
which is the same as $b = (1 && 5) (assignment "returns" the assigned value) and assigns 5 to $b.
The bottom line is: The operator precedence is the same in Perl and PHP (at least in this case), but they differ in what value is returned by the boolean operators.
FWIW, PHP's operator precedence can be found here.
What's more interesting (at least this was new to me) is that PHP does not perform type conversion for the increment/decrement operators.
So if $b is true, then $b++ leaves the value as true, while e.g. $b += 1 assigns 2 to $b.
†: What I mean with this is that it returns the first (leftmost) value which
evaluates to false in case of &&
evaluates to true in case of ||
or the last value of the expression.
First example
$a = 2;
$b = 3;
if($b=1 && $a=5) // means $b = (1 && $a=5)
{
var_dump($b); //bool(true) because of &&
$a++;
$b++; //bool(true)++ ==true, ok
}
echo $a.'-'.$b;
hope you will not use those codes in production)
I'm noob in perl but i can suggest a&&b returns a or b (last of them if all of them converted to bool), not boolean, then $b = (1 && $a=5) returns $b=5 (is 5)
here's the issue: 1 && 5 returns 5 in perl. you get the result you expect if you code the conditional as if(($b=1) && ($a=5))
For Perl, fig. 2: and has a very low priority in perl, it's not a synonym of &&'s. Therefore the sample is executed as (($a = 5) and ($b = 1)) which sets $a and $b to 5 and 1 respectively and returns a value of the last argument (i.e. 1).
After ++'s you get 6-2.
refer to http://sillythingsthatmatter.in/PHP/operators.php for good examples

PHP considers null is equal to zero

In PHP, ($myvariable==0)
When $myvariable is zero, the value of the expression is true; when $myvariable is null, the value of this expression is also true. How can I exclude the second case? I mean I want the expression to be true only when $myvariable is zero. Of course I can write
($myvariable != null && $myvariable == 0)
But is there other elegant way to do this?
$myvariable === 0
read more about comparison operators.
You hint at a deep question: when should an expression be true?
Below, I will explain why what you are doing isn't working and how to fix it.
In many languages null, 0, and the empty string ("") all evaluate to false, this can make if statements quite succinct and intuitive, but null, 0, and "" are also all of different types. How should they be compared?
This page tells us that if we have two variables being compared, then the variables are converted as follows (exiting the table at the first match)
Type of First Type of Second Then
null/string string Convert NULL to "", numerical/lexical comparison
bool/null anything Convert to bool, FALSE < TRUE
So you are comparing a null versus a number. Therefore, both the null and the number are converted to boolean. This page tells us that in such a conversion both null and 0 are considered FALSE.
Your expression now reads, false==false, which, of course, is true.
But not what you want.
This page provides a list of PHP's comparison operators.
Example Name Result
$a == $b Equal TRUE if $a equals $b after type juggling.
$a === $b Identical TRUE if $a equals $b, AND they are of the same type.
$a != $b Not equal TRUE if $a not equals $b after type juggling.
$a <> $b Not equal TRUE if $a not equals $b after type juggling.
$a !== $b Not identical TRUE if $a not equals $b, or they are not of the same type.
$a < $b Less than TRUE if $a is strictly less than $b.
$a > $b Greater than TRUE if $a is strictly greater than $b.
$a <= $b Less than/equal TRUE if $a is less than or equal to $b.
$a >= $b Greater than/equal TRUE if $a is greater than or equal to $b.
The first comparator is the comparison you are using now. Note that it performs the conversions I mentioned earlier.
Using the second comparator will fix your problem. Since a null and a number are not of the same type, the === comparison will return false, rather than performing type conversion as the == operator would.
Hope this helps.
To identify as null or zero by:
is_int($var) if a variable is a number or a numeric string. To identify Zero, use is_numeric($var) is also the solution or use $var === 0
is_null($var) if a variable is NULL
Try ($myvariable === 0) which will not perform type coercion.
Use the php function is_null( ) function along with the === operator. !== also works the way you'd expect.
The second solution wouldn't work either. The === operator is the solution to your problem.
If your zero could be a string, you should also considere checking the "zero string"
($myvariable === 0 || $myvariable === '0')
I hade faced a similar issue in one of my projects, with a minor difference that I was also using the values ZERO as a valid value for my condition. here's how I solved it using simple logic to separate NULL from zero and other values.
if (gettype($company_id) === 'NULL') {
$company = Company::where('id', Auth::user()->company_id)->first();
} else {
$company = Company::where('id', $company_id)->first();
}
$myvariable===0
$a === $b
Identical TRUE if $a is equal to $b, and they are of the same type
There's an is_null function, but this will just replace your $myvariable!=null
For my case i found this soulution and it works for me :
if ($myvariable === NULL) {
codehere...
}

Categories