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

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;
}
}

Related

Unable to populate cell by zero value from $_GET array

I am having an issue - I am unable to get a td cell when my $v value is 0. For all other numbers it is fine, but with zero value I just don't get then td.. What could be wrong? I am using $_GET array with a foreach loop, taking data from two inputs, one for name, one for value.
<table border = "1" >
<?php
print_r($_GET);
foreach ($_GET as $k=>$v){
if($v){
if ($rowFinished) echo "<tr>";
if (preg_match("/{$inputVardas}/i", $k))
{
echo "<td>$v</td>";
$rowFinished = false;
}
else if (preg_match("/{$inputSkaicius}/i", $k) and is_numeric($v))
{
if ($v < 10)
{
$color="green";
}
else if ($v > 10)
{
$color="red";
}
else if( $v == 10){
$color="yellow";
}
echo "<td style='color: $color'>$v</td>";
$rowFinished = true;
}
if ($rowFinished) echo "</tr>";
}
}?></table>
I've tried to do some print_r of an array, there I can see a value, but in my loop it just doesn't work. Maybe it has to do something with the case that php treats it as empty, but I am unable to find a way to use it.
[vardas0] => jonas [value0] => 0
Directly after the foreach you have a if ($v), and if the value is 0, it will not run.
I've found a way by improving the following line from
if($v){
to
if($v or (is_numeric($v) and $v == 0)){
It looks like you're using this
if ($v) {
to check that $v has a value. You can use
if (strlen($v)) {
instead.
Everything in $_GET will be a string, but a string '0' will evaluate as false just like an int 0 as you have discovered. Checking the length of the string instead will tell you whether or not that URL parameter has any value, including '0'.
You may also want to consider trimming the value before checking it if you want to exclude values containing only whitespace.
$v = trim($v);
if (strlen($v)) {
I honestly would suggest using isset()instead of all the provided suggestions so far. The reason is that to me it is best practice to have your conditionals be a boolean expression or something that explicitly evaluates to true or false. This avoids ambiguity and unintended side effects as evidenced by this question.
I would personally use:
if(isset($v)){

What is a shorthand way for checking that multiple variables are ALL equal to the same value in an IF statement? (PHP)

Is there a shorthand way of writing the code below?
if (($tstat=='no_prices')&&($l1stat=='no_prices')&&($l2stat=='no_prices')&&($l3stat=='no_prices'))
{
//do something
}
I tried using the below code,but it did something when one of the variables was not equal to 'no_prices'.
if (($tstat && $l1stat && $l2stat && $l3stat)=='no_prices')
{
//do something
}
To check that the strings weren't causing problems I tried substituting 0 for 'no_prices' and 1 for other values, but the result was the same.
array_flip is several times faster than array_unique:
function all_equal($arr, $value) {
return array_keys(array_flip($arr)) == array($value);
}
$arr = array($tstat, $l1stat, $l2stat, $l3stat);
echo all_equal($arr, 'no_prices');
A quick profile for the answers given thus far, for 1000 iterations on array length 1000:
array_flip: 0.07321620 seconds
array_unique: 0.32569408 seconds
foreach: 0.15136194 seconds
array_filter: 0.41404295 seconds
The code used to profile is here: http://codepad.org/szgNfWHe
Note: As #cypherabe rightly points out, array_flip does not overtake array_unique until the array has at least 5 elements, and does not overtake foreach until the array has at least 10 elements.
Unless I'm mistaken, there's no native way of doing this. If this is something that you have to check for often, try using a custom function for it, e.g.:
function allEquals($chkstr, $vals) {
if (!is_array($vals)) { die('allEquals() $vals not an array'); }
foreach ($vals AS $v) {
if ($chkstr != $v) { return false; }
}
return true;
}
My first idea would go into PHP's Array API:
// $tstadt, $l1stat, … are all "no_prices"
$isAllNoPrice = array_unique(array($tstat, $l1stat, …)) == array("no_prices"));
if ($isAllNoPrice) {
// …
}
Documentation is mandatory otherwise nobody (including yourself) will understand the code.
If efficiency might be a concern others pointed out that array_unique() seems to be slow. Using the keys of the hash table would be a next approach:
// $tstadt, $l1stat, … are all "no_prices"
$varsMap = array(
$tstat => null,
$l1stat => null,
// …
);
if (array_keys($varsMap) == array("no_prices")) {
// …
}
But now the wall of code is growing. PHP offers one operator which nearly does what you want and is chainable: &
$v1 = "no_prices";
$v2 = "no_prices";
$v3 = "no_prices";
var_dump(($v1 & $v2 & $v3) == "no_prices"); // bool(true)
$v3 = "prices";
var_dump(($v1 & $v2 & $v3) == "no_prices"); // bool(false)
I said it nearly does what you want: There are cases in which you will have false positives:
$v1 = 1;
$v2 = 1;
$v3 = 3;
var_dump(($v1 & $v2 & $v3) == 1); // bool(true)
For Strings it seems to cut the bitmask to the shortest string:
$v1 = "abcd";
$v2 = "ab";
$v3 = "abc";
var_dump($v1 & $v2 & $v3); // "ab"
var_dump(($v1 & $v2 & $v3) == "ab"); // bool(true)
So I don't recommend this as a general purpose solution. Only if you know (=unit tested) that your values are in a set where no combination never results to a false positive (e.g. {"dog", "cat", "horse"}) you might consider this solution. I gave it a second thought and must say don't use that at all. Imagine how your colleagues will love you for searching a bug introduced by that method.
In your case you can do:
if (count(array_unique($tstat, $l1stat, $l2stat, $l3stat)) == 1 //Check if all share the same value (i.e., number of unique values is 1
&& $tstat == 'no_prices')) //If everything is the same and $stat == 'no_prices', then everything is 'no_prices'
{
}
<?php
$tstat = $l1stat = $l2stat = $l3stat = 'no_prices';
$testVars = array($tstat,$l1stat,$l2stat,$l3stat);
if(count(array_filter($testVars, function($x) { return $x === 'no_prices'; })) == count($testVars))
{
print("Correct");
}
Use array_filter with a anonymous callback, and check if its length is greater is equal to original array i.e. all conditions passed,
or if length is greater than zero i.e. any one condition passed
No, this code won't work:
if (($tstat&&$l1stat&&$l2stat&&$l3stat)=='no_prices')
{
//do something
}
Why? Because condition in parentheses, will check result itself - You are comparing boolean to string. So in pseudo-code, thats what your code looks like:
if ( ($tstat is true, $l1stat is true, $l2stat is true, $l3stat is true) == 'no_prices' )
^ whole thing returns true ^ ^ true ^
If you wan't to achieve this, you can use count() and array_unique():
if ($tstat == 'no_prices' && count(array_unique(array($tstat, $l1stat, $l2stat, $l3stat))) == 1)
try this:
$arr = array($tstat,$l1stat,...); //make an array
$arr =array_unique($arr);//unique this array
if(count($arr) == 1 && $arr[0] = 'no_prices'){ // check if only one array element have with same value
echo "got it";
}
demo example
The answer is "no". There's no shorthand to the given condition that will make your code more readable, which should be your top priority. You can improve it though:
define('MYAPP_NO_PRICES', 'no_prices');
if ($tstat === MYAPP_NO_PRICES
&& $l1stat === MYAPP_NO_PRICES
&& $l2stat === MYAPP_NO_PRICES
&& $l3stat === MYAPP_NO_PRICES) {
// do something
}
Having all these vars to check individually is a code smell; you might want to rethink this design so you never have to do this.

How to check if an associative array has an empty or null value

In the following associative array
$array = array(
[0] => 0
[1] => 1
[2] =>
[3] => 2
[4] =>
)
how can you determine if a given key has an empty (or null) value? I used
if(empty($array[$value]))
and
if(isset($array[$value])) && $array[$value] !=='')
When using empty I also get false for the first array value which is zero and isset doesn't seem to do the trick.
use array_key_exists() and is_null() for that. It will return TRUE if the key exists and has a value far from NULL
Difference:
$arr = array('a' => NULL);
var_dump(array_key_exists('a', $arr)); // --> TRUE
var_dump(isset($arr['a'])); // --> FALSE
So you should check:
if(array_key_exists($key, $array) && is_null($array[$key])) {
echo "key exists with a value of NULL";
}
Looked at all the answers and I don't like them. Isn't this much simpler and better? It's what I am using:
if (in_array(null, $array, true) || in_array('', $array, true)) {
// There are null (or empty) values.
}
Note that setting the third parameter as true means strict comparison, this means 0 will not equal null - however, neither will empty strings ('') - this is why we have two conditions. Unfortunately the first parameter in in_array has to be a string and cannot be an array of values.
PHP empty return values states:
Returns FALSE if var exists and has a non-empty, non-zero value. Otherwise returns TRUE.
The following things are considered to be empty:
"" (an empty string)
0 (0 as an integer)
0.0 (0 as a float)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
$var; (a variable declared, but without a value)
From your array example I take it as you want to exclude the 0 as an integer. If that's the case this would do the trick:
<?php
$array = array(0, 1, '', 2, '');
foreach ($array as $value) {
echo (empty($value) && 0 !== $value) ? "true\n" : "false\n";
}
If you want to exclude other conditions that empty considers just negate them in that condition. Take in account that this might not be the optimal solution if you want to check other values.
if ( !isset($array[$key]) || $array[$key] == "" || is_null($array[$key]) )
{
//given key does not exist or it has "" or NULL value
}
foreach($array as $i => $v) {
if(null === $v) {
// this item ($array[$i]) is null
}
}
...or, for a given key:
if(null === $array[2]) {
// this item ($array[2]) is null
}
Potentially this could be cleaner if I knew how the array was constructed, but, having the assumption that you can have both empty strings, or nulls in the array, and you want to account for values of 0 --> here's what I'd do:
if (is_null($array[$key]) || (string)$array[$key] == '')
Here's a little bit of test code showing it in action with an array that has both 0, null, an empty string, and non-zero integers...
$array = array(0,1,null,2,'');
print_r($array);
foreach ($array as $key => $val) {
if (is_null($array[$key]) || (string)$array[$key] == '') {
echo $key.", true\n";
}
}
As for using isset() -- an empty string is consider to be set. Which may be what you're running into (aside from 0 being considered empty) Compare with this usage:
$foo = array(0,1,null,2,'');
print_r($foo);
foreach ($foo as $key => $val) {
if (isset($foo[$key])) {
echo $key.", true\n";
}
}
function is_empty($data){
$is_empty = true;
foreach ($data as $val){
if(is_array($val)){
$is_empty = is_empty($val);
}else{
if(!empty($val)){
$is_empty = false;
break;
}
}
}
return $is_empty;
}

Why does (0 == 'Hello') return true in PHP?

Hey, if you have got the following code and want to check if $key matches Hello I've found out, that the comparison always returns true if the variable is 0. I've came across this when an array for a special key and wondered why it's wasn't working as expected.
See this code for an example.
$key = 1;
if ($key != 'Hello') echo 'Hello'; //echoes hello
$key = 2;
if ($key != 'Hello') echo 'Hello'; //echoes hello
$key = 0;
if ($key != 'Hello') echo '0Hello'; //doesnt echo hello. why?
if ($key !== 'Hello') echo 'Hello'; //echoes hello
Can anyone explain this?
The operators == and != do not compare the type. Therefore PHP automatically converts 'Hello' to an integer which is 0 (intval('Hello')). When not sure about the type, use the type-comparing operators === and !==. Or better be sure which type you handle at any point in your program.
Others have already answered the question well. I only want to give some other examples, you should be aware of, all are caused by PHP's type juggling. All the following comparisons will return true:
'abc' == 0
0 == null
'' == null
1 == '1y?z'
Because i found this behaviour dangerous, i wrote my own equal method and use it in my projects:
/**
* Checks if two values are equal. In contrast to the == operator,
* the values are considered different, if:
* - one value is null and the other not, or
* - one value is an empty string and the other not
* This helps avoid strange behavier with PHP's type juggling,
* all these expressions would return true:
* 'abc' == 0; 0 == null; '' == null; 1 == '1y?z';
* #param mixed $value1
* #param mixed $value2
* #return boolean True if values are equal, otherwise false.
*/
function sto_equals($value1, $value2)
{
// identical in value and type
if ($value1 === $value2)
$result = true;
// one is null, the other not
else if (is_null($value1) || is_null($value2))
$result = false;
// one is an empty string, the other not
else if (($value1 === '') || ($value2 === ''))
$result = false;
// identical in value and different in type
else
{
$result = ($value1 == $value2);
// test for wrong implicit string conversion, when comparing a
// string with a numeric type. only accept valid numeric strings.
if ($result)
{
$isNumericType1 = is_int($value1) || is_float($value1);
$isNumericType2 = is_int($value2) || is_float($value2);
$isStringType1 = is_string($value1);
$isStringType2 = is_string($value2);
if ($isNumericType1 && $isStringType2)
$result = is_numeric($value2);
else if ($isNumericType2 && $isStringType1)
$result = is_numeric($value1);
}
}
return $result;
}
Hope this helps somebody making his application more solid, the original article can be found here:
Equal or not equal
pretty much any non-zero value gets converted to true in php behind the scenes.
so 1, 2,3,4, 'Hello', 'world', etc would all be equal to true, whereas 0 is equal to false
the only reason !== works is cause it is comparing data types are the same too
Because PHP does an automatic cast to compare values of different types. You can see a table of type-conversion criteria in PHP documentation.
In your case, the string "Hello" is automatically converted to a number, which is 0 according to PHP. Hence the true value.
If you want to compare values of different types you should use the type-safe operators:
$value1 === $value2;
or
$value1 !== $value2;
In general, PHP evaluates to zero every string that cannot be recognized as a number.
In php, the string "0" is converted to the boolean FALSE http://php.net/manual/en/language.types.boolean.php

PHP Associative array

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.

Categories