I have these arrays : $_POST['atlOriginal'] and $oldAtlPos. The values stored of both are this :
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
Now, if I done this comparison $_POST['atlOriginal']===$oldAtlPos it returns false, because $_POST['atlOriginal'] values are Strings (the are passed trought GET/POST from client) and $oldAtlPos values are Integer.
What can I do here? What's the best strategy? Convert one in another?
P.S. I need to valutate the order of the values, so === is necessary;
P.S. 2 Values of Both will be stored in the database as Char(2);
EDIT
So :
for($i=0; $i<sizeof($oldAtlPos); $i++) echo $_POST['atlOriginal'][$i]."|".gettype($_POST['atlOriginal'][$i])." - ".$oldAtlPos[$i]."|".gettype((string)$oldAtlPos[$i])."<br/>";
will return :
0|string - 0|string
1|string - 1|string
2|string - 2|string
3|string - 3|string
4|string - 4|string
5|string - 5|string
6|string - 6|string
7|string - 7|string
8|string - 8|string
9|string - 9|string
10|string - 10|string
11|string - 11|string
12|string - 12|string
13|string - 13|string
14|string - 14|string
15|string - 15|string
16|string - 16|string
17|string - 17|string
18|string - 18|string
But seems that if($_POST['atlOriginal']===(string)$oldAtlPos) still return false...
Do not compare values with their types using ===.
Compare just only values using ==.
Edit:
For example, there are:
$a = array(1, 2, 3);
$b = array('1', '2', '3');
and then when you compare those arrays in 2 ways (== and ===), you will get following results:
$a == $b; // TRUE
$a === $b; // FALSE
So as you can see, what you need is to use == compare method.
Edit 2:
In your P.S. you say that you need to compare arrays order too.
It does it already. If you compare arrays like that you will get false:
$a = array(3, 2, 1);
$b = array('1', '2', '3');
$a == $b; // FALSE
If you are trying to compare them you could:
use == instead of === (recommended)
== means 'do these values match'
=== means 'do these values match and are they of the same type'
$foo['test'] = Array("1","2","3");
$bar = Array(1,2,3);
$baz = Array(3,2,1);
var_dump($foo['test'] === $bar); // FALSE - does not work
var_dump($foo['test'] === (string) $bar); // FALSE - does not work
var_dump($foo['test'] == $bar); // TRUE - works!
var_dump($foo['test'] == $baz); // FALSE - works because $baz is in a different order
== does not check key/value pair order however since you are only using values, the key is essentially the order and matches (so this does what you want)
From this above code, this is what the array actually looks like
$foo['test']
array(3) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
[2]=>
string(1) "3"
}
$bar
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
== checks to make sure the key (the part in []) and value (int() in this case) match, it does not check order -- but this does not matter since you are only using values and the key is the order.
The only time this would affect you is if you were using key/value pairs and wanted to check order such as:
// key/value pairs match but order does not
Array('1' => 'B', '0' => 'A') === Array('0' => 'A', '1' = 'B') // FALSE
Array('1' => 'B', '0' => 'A') == Array('0' => 'A', '1' = 'B') // TRUE -- order is not checked
Fix: If you are using Key=>Value pairs then this will do the trick:
// Function to fix data
function array_fix(&$item, $key)
{
$item = intval($item);
}
$foo['test'] = Array(1=>"1",2=>"2",3=>"3");
$bar = Array(1=>1,2=>2,3=>3);
$baz = Array(2=>2,1=>1,3=>3);
// str !== int
var_dump($foo['test'] === $bar); // FALSE
// Apply fix to all data in array
array_walk($foo['test'],'array_fix');
// int === int -- yay :-D
var_dump($foo['test'] === $bar); // TRUE
var_dump($foo['test'] === $baz); // FALSE - correct: out of order
you have to iterate though each elements and compare them individually
Related
In what ways can one determine whether the value of an array's index is falsey due to an out-of-bounds index in PHP?
For example, one might erroneously conclude that both $a and $b below have at least three items each, since the comparison of the third items in both arrays purport to have identical values at index 2, when in reality there is no index 2 in array $b. Indeed both values are null.
$a = array(1, false, null, 1, 0);
$b = array(true, 0);
echo (int)($a[0] === $b[0]); // 0
echo (int)($a[1] === $b[1]); // 0
echo (int)($a[2] === $b[2]); // 1 null<declared>===null<index-out-of-bounds>
echo (int)($a[3] === $b[3]); // 0
echo (int)($a[4] === $b[4]); // 0
Interesting question... Maybe somthing like this (but only for numeric array indexes):
(int)(count($a)>=$i && count($b)>=$i && $a[$i]===$b[$i])
?
EDIT: probably better solution based on array_key_exists:
(int)(array_key_exists($i, $a) && array_key_exists($i, $b) && $a[$i]===$b[$i] )
I have an array that can have a key "d" or not. The values associated with "d" comes from a mysql query. I don't want to show "d"'s value when it is
NULL
"NULL"
""
less than 0
So I have this scenario:
// should show
$a = array("a"=>1,"b"=>NULL,"c"=>"zzz");
if ($a["d"] >= 0) {
echo "show";
}
// should show
$a = array("a"=>1,"b"=>NULL,"c"=>"zzz","d"=>NULL);
if ($a["d"] >= 0) {
echo "show";
}
It seems that php is recognizing NULL as 0 when "d"=>NULL. What is the best way to test those conditions without using array_key_exists?
The reason that you think php is interpreting the value as 0 is because when you do the comparison, you're using >=.
>= will typecast the left value to the type of the right-side value. So the comparison actually looks more like
((int) $a["d"]) >= 0
and null, when cast to an int, is 0.
you can also check for the existence of that array index using
isset($a['d'])
or
empty($a['d'])
This is the downside of having a loosely typed language, it gets confusing if you don't fully understand whats goin on. check this out for a bunch more information
isset is your friend
<?php
$ar_list = array(
array('d' => null),
array('d' => 0),
array('d' => 12),
);
foreach ($ar_list as $ar) {
if (isset($ar['d']) && $ar['d'] >= 0) {
echo "{$ar['d']}\n";
};
};
The above example will output:
0
12
I have the following PHP expression
($g == $key)
Values: $g = objid and $key = 0
If I dump the expression
var_dump(array($g == $key,$g, $key));
the result is
array(3) { [0]=> bool(true) [1]=> string(5) "objid" [2]=> int(0) }
Why is it showing true? I solve the problem using === in my expression but I would like to know why is this happening.
PHP is converting your "objid" to an int, and is probably making it a 0, so yeah, your "integerized string" is really equal to 0.:
php > var_dump(' ' == 0, 'foobar' == 0, 'objid' == 0);
bool(true)
bool(true)
bool(true)
Note that if your 'objid' string STARTED with a number, then it would kinda/sorta/not-really work:
php > var_dump('a1b' == 0, '1ab' == 0);
bool(true)
bool(false)
And using the strict comparison === operator would also solve this. It compares values AND types. while 'foo' == 0 is true, 'foo' === 0 is false.
From the manual:
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.
"objid " is not a valid number so it's converted to 0.
The === is a type-safe equality operator - it makes sure that the objects you are comparing are of the same type.
== checks if the two objects have the same 'truthy' or 'falsey' value.
Ex:
0 == '0'
is true because '0' is considered a falsey value, but
0 === '0'
is false because one's an int and the other's a string
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);
I'm reading about php and it says,
== is Equality such that $a == $b is true if $a and $b have the same elements.
=== is Identity such that $a === $b is true if $a and $b have the same elements, with the same types, in the same order.
So, I thought I'd try and see the difference myself and wrote with this little script:
$a = array(1, 2, 3);
$b = array(2, 3, 1);
if ($a==$b) {echo "yeehaw!";} else {echo "nope";}
if ($a===$b) {echo "yup";} else {echo "nope";}
My thought was that the same order wasn't required for two arrays to be equal. However, when I ran this, I got "nope" and "nope".
What is the difference?
The arrays you've provided have the same set of values, but different key-value-pairs.
Try the following use case instead (same key-value-pairs in different order):
$a = array(0=>1, 1=>2, 2=>3);
$b = array(1=>2, 2=>3, 0=>1);
... and the following use case (different data types):
$a = array(1, 2, 3);
$b = array('1', '2', '3');
The documentation[PHP.net] says:
== TRUE if $a and $b have the same key/value pairs.
=== TRUE if $a and $b have the same key/value pairs in the same order and of the same types.
Since your two arrays are not in the same order1, they don't have the same key-value pairs.
var_dump($a);
array(3) {
[0]=> int(1)
[1]=> int(2)
[2]=> int(3)
}
var_dump($b);
array(3) {
[0]=> int(2)
[1]=> int(3)
[2]=> int(1)
}
1 With regards to their construction via array(), which will index the arguments starting with 0.
My thought was that the same order wasn't required for two arrays to be equal.
To make it clear what the documentation meant by same key/value pairs, let's take a look at the actual array contents:
$a = array(
0 => 1,
1 => 2,
2 => 3,
);
$b = array(
0 => 2,
1 => 3,
2 => 1,
);
Clearly, the pairs are different.
So what about that "same order"?
To illustrate that, let's create $b a little different:
$b => array(
2 => 3,
1 => 2,
0 => 1,
);
The == equality will be satisfied because the pairs are now the same. However, because arrays in PHP are ordered maps, a difference in pair order causes the === equality to fail.
Two arrays are considered identical === if:
number of elements is the same
all data types are the same
all elements are in the same order
each array has the same key-value pairs
What is the difference?
The difference between two arrays can mean different things, so this question is normally best answered by using the kind of difference function for arrays that match your expectations.
In your case, equality is (probably) satisfied by the array_diff() function:
!array_diff($a, $b) && !array_diff($b, $a);
If you say no, that's not what I'm looking for, please see the duplicate question "PHP - Check if two arrays are equal" I also left an extended answer there that shows the other possible differences and how to test for those as you're concerned about comparing values and not element (which are key/value pairs).
1st one fails because the elements are different. 2nd one fails because elements are different although type is same. (both should same)