PHP Associative array - php

I have an array as
$arrTest = array('val1','val2','val3','val4');
$arrTest['lastKey'] = 'Last Key';
foreach($arrTest as $key => $val) {
if($key == 'lastKey') {
echo "last found";
}
}
The above code is not working. I have added associative element in the array. Could it be the reason?

Change == to === in:
if($key == 'lastKey')
Your existing code echos last found twice, once for key 0 and once for key lastKey.
Comparing integer 0 and string 'lastKey' using == returns true !!
From the PHP manual:
String conversion to numbers
When a string is evaluated in a
numeric context, the resulting value
and type are determined as follows.
The string will be evaluated as a
float if it contains any of the
characters '.', 'e', or 'E'.
Otherwise, it will be evaluated as an
integer.
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). Valid numeric
data is an optional sign, followed by
one or more digits (optionally
containing a decimal point), followed
by an optional exponent. The exponent
is an 'e' or 'E' followed by one or
more digits.

Use === to compare. Because when key 0 will be compared with string lastKey, string will be converted to integer and false result will be returned.
http://codepad.org/5QYIeL4f
$arrTest = array('val1','val2','val3','val4');
$arrTest['lastKey'] = 'Last Key';
foreach($arrTest as $key => $val) {
if($key === 'lastKey') {
echo "last found";
}
}
Read more about differences: http://php.net/manual/en/language.operators.comparison.php

You need to change your equality condition to check the type as well.
if($key === 'lastKey')
This is because PHP evaluates ' ' == 0 as true.

When I ran your code, 'last found' was outputted twice. 'lastKey' is evaluated to 0 in PHP, so if($key == 'lastKey') actually matches twices: once for 0 and once for your special element.

use the end() function to get the last key of an array and compare it in your if statement.
$arrTest = array('val1','val2','val3','val4');
$lastKey = end($arrTest);
foreach($arrTest as $key => $val) {
if($val == $lastKey) {
echo "last found";
}
}

Your code is working fine :
see it here : http://codepad.org/hfOFHMnc
However use "===" instead of "==" as you might encounter a bug when
comparing the string with 0 , and it will echo twice.
<?php
$arrTest = array('val1','val2','val3','val4');
$arrTest['lastKey'] = 'Last Key';
print_r($arrTest);
foreach($arrTest as $key => $val) {
if($key == 'lastKey') { // use === here
echo "key = $key :: last found \n";
}
}

If you want to test if an array key exists, simply use array_key_exists:
array_key_exists('lastKey', $arrTest)
You could also use isset but note that it returns false if the value associated to the key is null.

Related

PHP populated field returns 0 even if populated

I have a MySQL row I get data from by doing this:
...['immobile' => $dati_immobile->row(),]...
I then have a table and I pass every field inside a function, this is the function code:
public function brochurefield($field, $label, $checkbox = false)
{
if($field == 0){
return '<tr><td>'.$label.' Is zero</td></tr>';
}
}
When I echo this function with a text field taken from the MySQL it returns 0:
//This returns "Accessori Bagno Is zero"
<?= $this->ui_model->brochurefield($immobile->arredo_bagno, "Accessori Bagno") ?>
//This returns "termo arredo" (text from DB)
<tr><td><?= $immobile->arredo_bagno ?></td></tr>
It basically reads the field to be 0 instead of "termo arredo".
While if I check the field on $field == "0" (string) and $field == '' (empty string) the result is false.
The result is true only when I check it against a 0 (int) value.
The problem happens only on string values, while on int values I get the expected results (brochurefield(32,"test") returns correctly the number 32).
I use PHP 7.1.1
You have to use your if condition like.
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). Valid numeric data is an
optional sign, followed by one or more digits (optionally containing a
decimal point), followed by an optional exponent. The exponent is an
'e' or 'E' followed by one or more digits.
This means that:
("test" == 0) === true
("1test" == 0) === false
if ($field == "" || $field == "0" || (is_numeric($field) && $field == 0)) {
For more reference you can visit PHP manual

foreach, unexpected result for element, which key is 0

I have this code
$arr = array(
"0"=>"http://site.com/somepage/param1/param2/0",
"1"=>"http://site.com/somepage/param1/param2/1",
"thispage" => "http://site.com/somepage/param1/param2/2",
"3"=> "http://site.com/somepage/param1/param2/3"
);
foreach ($arr as $k=>$v) {
if ($k == "thispage") {
echo $k." ";
}
else {
echo ''.$k.' ';
}
}
Its surprise, for first element "0"=>"http://site.com/somepage/param1/param2/0", not created link, (for other elements works fine)
If replace first element key 0 on something other, for example 4, now links created. What is wrong ?
This is happening because 0 == "thispage" and the first key is 0. To find out more about this, take a look at the PHP manual page about Type Juggling.
Use === ("is identical to") instead of == ("is equal to"), because 0 is equal to "thispage", but not identical.
This is what happens with ==:
$key takes the integer value of 0
PHP tries to compare 0 == "thispage"
in order to make the comparison, it needs to cast "thispage" to integer
the resulting comparison is 0 == 0, which is true
If you use ===:
$key takes the integer value of 0
PHP tries to compare 0 === "thispage"
since 0 is of a different type (integer) than "thispage" (string), the result is false
This is What you are doing wrong.
if ($k === "thispage") {
echo .$k." ";
}
Do the:
if ($k === "thispage")
You have to use identical comparison operator === as equal comparison operator won't help here, because
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.
thispage converted to number will return 0, so your if statement will match if you use equal comparison operator ==. When you do identical comparison === if type does not match it returns false.
You can read about comparison operators here.
Try this:
if ($k === "thispage") {
echo $k." ";
}
http://us.php.net/manual/en/language.types.array.php:
A key may be either an integer or a string. If a key is the standard representation of an integer, it will be interpreted as such (i.e. "8" will be interpreted as 8, while "08" will be interpreted as "08").
So in your case Stings "1", "2" and "3" are treated as integers.
To fix this use the === operator that check for type along with value.
The reason for the result you see is the comparison operator you use. == is too imprecise sometimes and can result in wierd things like this. Using the === will compare the values for exactness and will prevent the issue you have.
so:
foreach ($arr as $k=>$v) {
// this is the important thing
if ($k === "thispage") {
echo $k." ";
}
else {
echo ''.$k.' ';
}
}

Weird $key => $value comparison with PHP

I'm facing a weird issue with PHP. This simple example:
<?php
$array = array(
'zero',
'one',
'id' => 'two'
);
foreach ($array as $key => $value) {
if ($key == "id") {
echo "Key: ". $key .", value: ". $value ."\n";
}
}
?>
should (imho) output this:
Key: id, value: two
But it outputs
Key: 0, value: zero
Key: id, value: two
How is this possible: 0 == "id"?
When $key is 0 and gets compared to the string "id", the string ("id") will be converted to an integer. Since "id" can't be turned into a valid integer that conversion will yield 0, and the if statement becomes true.
Since you don't want the implicit conversion to happen between two types who aren't compatible use the more strict === version of ==. === will see if the variables are of the same type and has the same exact value.
if ($key === "id") {
...
}
Documentation PHP: Comparison Operators
Examples
var_dump (0 == (int)"id");
var_dump ((string)0 == "id");
var_dump (0 === "id");
var_dump (1.0 === 1);
output
bool(true)
bool(false)
bool(false)
bool(false) # be careful!
You are being bitten by a process called type juggling.
Try the following:
var_dump(0 == "id");
It will output bool(true).
PHP is performing integer comparison, and when it attempts to convert the string "id" to an integer, the result is 0. PHP will happily parse leading digits of a string and stop at the first non-numeric value, yielding integer 123 for strings like "123xyz". Because there are no leading digits in the string "id", it is parsed as integer 0.
The solution is to use ===, which compares the value and type of two variables, without attempting to juggle the types of the operands.
This:
$key == 'id'
...will make PHP do integer comparison, since the lvalue is an integer.
If you're wondering why this:
if ($key) { ... }
...wouldn't give the same result, well it's because the lvalue here (while omitted) is boolean, equivalent to:
if (true == $key) { ... }
Therefore, PHP will attempt boolean comparison. You can use the === operator to force a type check.
You can refer to the Type Comparison Tables and the Comparison Operators Table.
If you set the logic expression to take into account vartype
if (key === "id")
if will work. Just like #refp says.

Doctrine fromArray bug?

I have a problem with doctrine with this code I can't explain.
public function fromArray(array $array, $deep = true) {
$refresh = false;
foreach ($array as $key => $value) {
if ($key == '_identifier') {
$refresh = true;
$this->assignIdentifier($value);
continue;
}
My key (integer) 0 will equal (string) '_identifier'. Is this a bug in PHP or is this normal? or am I doing something wrong?
When I change the code to $key === '_identifier' it works. I have PHP version 5.3.4
That's PHP:
echo (int) '_identifier'; // 0
And 0 equals 0. In the comparison operation the string is changed into integer to compare it.
Use === to do a comparison of the same type as well. Called identical, not equal:
public function fromArray(array $array, $deep = true) {
$refresh = false;
foreach ($array as $key => $value) {
if ($key === '_identifier') {
$refresh = true;
$this->assignIdentifier($value);
continue;
}
As far as I understand:
== is just generic comparing, so if your key is an integer it will convert the string to an integer to compare it and from the manual:
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). Valid numeric
data is an optional sign, followed by
one or more digits (optionally
containing a decimal point), followed
by an optional exponent. The exponent
is an 'e' or 'E' followed by one or
more digits.
=== is strict evaluation so it compares types too.
So when you do "0 == '_identifier'" it passes as it evaluated '_identifier' as 0.
When you do "0 === '_identifier'" it does not pass as they are different types.

php, mysql, arrays - if( x == 0 ) { }

I have the following code
while($row = $usafisRSP->fetch_assoc())
{
$hidden_keys = array('Applicantid', 'unique_num', 'regs_time' ....);
$hidden_fields = array_intersect_key($row, array_fill_keys($hidden_keys, NULL));
$hidden_values = array();
foreach ($hidden_fields as $key => $value) {
// fill the values array using the values from fields array
$hidden_values[$value] = "$key = ".base64_decode($value)."";
if(base64_decode($value)== 0)
{
$hidden_values[$value] = "";
}
echo $hidden_values[$value];
The question is about "if($hidden_values[$value] == 0)" ... Basically I want to do not display/echo the $hidden_values[$value] if it's value of $value is 0. Sometimes $value is 0 or some words like (23 avenue).
I think you ran into three catches with PHP type comparisons and equalities:
Any string not beginning with a number will always loosely equal 0. So basically, if(base64_decode($value)== 0) will likely always resolve to true, even if decoded $value is "Adam".
Return value of base64_decode is a string, so if 0 is the result, it will be string 0, not integer 0. This means if(base64_decode($value) === 0) wouldn't even work if decoded $value is "0". Another catch is base64_decode may return false on errors, again failing this strict equality check.
A non-empty string (other than "0") will always loosely equal true. So this is the only comparison you really need for your case.
I think this is what you want, replacing the last 5 lines...
if(base64_decode($value)) echo $hidden_values[$value];
else $hidden_values[$value] = "";
} // closing your for loop
Is this what you're looking for?
foreach( $hidden_values as $value ) {
if( $value !== 0 ) {
echo $value;
}
}

Categories