Unable to populate cell by zero value from $_GET array - php

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)){

Related

Foreach() on Array

I understand that this foreach() statement is printing out the field 'name_first' from every item in the array that was fed to it...
foreach ($data as $author) {
print get('name_first', $author) .
" " . get('emailaddress', $author) .
"<br/>";
if(strpos($author['emailaddress'], ">")) {
$sp->update($listName, $author['id'], array('emailaddress'=> email_from_link($author['emailaddress'])));
}
But can someone just explain what the last if statement is doing? It really doesn't make any sense to me.
if(strpos($author['emailaddress'], ">")) {
$sp->update($listName, $author['id'], array('emailaddress'=> email_from_link($author['emailaddress'])));
It's checking for the character > in the string $author['emailaddress'] after the first character.
If > exists, then update the array $sp with the values specified between the parentheses.
It's asking of the position of the > character in the string. If the character is at any position other than the first character, the if-block will be entered.
This is what I'd consider sloppy/lazy programming - it's a bad idea to get in the habit of treating ints and booleans the same way, especially when a function like strpos can return an integer 0 and also false:
From the docs:
Warning This function may return Boolean FALSE, but may also return a
non-Boolean value which evaluates to FALSE.
Furthermore code like that ends up confusing people, as has happened in your case. Far better to code explicitly:
$index = strpos($author['emailaddress'], '>');
if(FALSE === $index) {
// Handle error
}
else if($index > 0) {
$sp->update($listName, $author['id'], array('emailaddress'=> email_from_link($author['emailaddress'])));
}
It's more verbose, certainly, but as a result it's easier to understand and therefore easier to maintain.

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.

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

Check if all values in array are the same

I need to check if all values in an array equal the same thing.
For example:
$allValues = array(
'true',
'true',
'true',
);
If every value in the array equals 'true' then I want to echo 'all true'. If any value in the array equals 'false' then I want to echo 'some false'
Any idea on how I can do this?
All values equal the test value:
// note, "count(array_flip($allvalues))" is a tricky but very fast way to count the unique values.
// "end($allvalues)" is a way to get an arbitrary value from an array without needing to know a valid array key. For example, assuming $allvalues[0] exists may not be true.
if (count(array_flip($allvalues)) === 1 && end($allvalues) === 'true') {
}
or just test for the existence of the thing you don't want:
if (in_array('false', $allvalues, true)) {
}
Prefer the latter method if you're sure that there's only 2 possible values that could be in the array, as it's much more efficient. But if in doubt, a slow program is better than an incorrect program, so use the first method.
If you can't use the second method, your array is very large, and the contents of the array is likely to have more than 1 value (especially if the 2nd value is likely to occur near the beginning of the array), it may be much faster to do the following:
/**
* Checks if an array contains at most 1 distinct value.
* Optionally, restrict what the 1 distinct value is permitted to be via
* a user supplied testValue.
*
* #param array $arr - Array to check
* #param null $testValue - Optional value to restrict which distinct value the array is permitted to contain.
* #return bool - false if the array contains more than 1 distinct value, or contains a value other than your supplied testValue.
* #assert isHomogenous([]) === true
* #assert isHomogenous([], 2) === true
* #assert isHomogenous([2]) === true
* #assert isHomogenous([2, 3]) === false
* #assert isHomogenous([2, 2]) === true
* #assert isHomogenous([2, 2], 2) === true
* #assert isHomogenous([2, 2], 3) === false
* #assert isHomogenous([2, 3], 3) === false
* #assert isHomogenous([null, null], null) === true
*/
function isHomogenous(array $arr, $testValue = null) {
// If they did not pass the 2nd func argument, then we will use an arbitrary value in the $arr (that happens to be the first value).
// By using func_num_args() to test for this, we can properly support testing for an array filled with nulls, if desired.
// ie isHomogenous([null, null], null) === true
$testValue = func_num_args() > 1 ? $testValue : reset($arr);
foreach ($arr as $val) {
if ($testValue !== $val) {
return false;
}
}
return true;
}
Note: Some answers interpret the original question as (1) how to check if all values are the same, while others interpreted it as (2) how to check if all values are the same and make sure that value equals the test value. The solution you choose should be mindful of that detail.
My first 2 solutions answered #2. My isHomogenous() function answers #1, or #2 if you pass it the 2nd arg.
Why not just compare count after calling array_unique()?
To check if all elements in an array are the same, should be as simple as:
$allValuesAreTheSame = (count(array_unique($allValues, SORT_REGULAR)) === 1);
This should work regardless of the type of values in the array.
Update: Added the SORT_REGULAR flag to avoid implicit type-casting as pointed out by Yann Chabot
Also, you can condense goat's answer in the event it's not a binary:
if (count(array_unique($allvalues)) === 1 && end($allvalues) === 'true') {
// ...
}
to
if (array_unique($allvalues) === array('foobar')) {
// all values in array are "foobar"
}
If your array contains actual booleans (or ints) instead of strings, you could use array_sum:
$allvalues = array(TRUE, TRUE, TRUE);
if(array_sum($allvalues) == count($allvalues)) {
echo 'all true';
} else {
echo 'some false';
}
http://codepad.org/FIgomd9X
This works because TRUE will be evaluated as 1, and FALSE as 0.
You can compare min and max... not the fastest way ;p
$homogenous = ( min($array) === max($array) );
$alltrue = 1;
foreach($array as $item) {
if($item!='true') { $alltrue = 0; }
}
if($alltrue) { echo("all true."); }
else { echo("some false."); }
Technically this doesn't test for "some false," it tests for "not all true." But it sounds like you're pretty sure that the only values you'll get are 'true' and 'false'.
Another option:
function same($arr) {
return $arr === array_filter($arr, function ($element) use ($arr) {
return ($element === $arr[0]);
});
}
Usage:
same(array(true, true, true)); // => true
Answering my method for people searching in 2023.
$arr = [5,5,5,5,5];
$flag = 0;
$firstElement = $arr[0];
foreach($arr as $val){
// CHECK IF THE FIRST ELEMENT DIFFERS FROM ANY OTHER ELEMENT IN THE ARRAY
if($firstElement != $val){
// FIRST MISMATCH FOUND. UPDATE FLAG VALUE AND BREAK OUT OF THE LOOP.
$flag = 1;
break;
}
}
if($flag == 0){
// ALL THE ELEMENTS ARE SAME... DO SOMETHING
}else{
// ALL THE ELEMENTS ARE NOT SAME... DO SOMETHING
}
In an array where all elements are same, it should always be true that all the elements MUST match with the first element of the array. Keeping this logic in mind, we can get the first element of the array and iterate through each element in the array to check for that first element in the loop which does not match with the first element in the array. If found, we will change the flag value and break out of the loop immediately. Else, the loop will continue till it reaches the end. Later, outside the loop, we can use this flag value to determine if all the elements in the array are same or not.
This solution is good for arrays with definite limit of elements (small array). However, I am not sure how good this solution would be for arrays with very large number of elements present considering that we are looping through each and every element to check for the first break even point. Please use this solution at your own convenience and judgement.
$x = 0;
foreach ($allvalues as $a) {
if ($a != $checkvalue) {
$x = 1;
}
}
//then check against $x
if ($x != 0) {
//not all values are the same
}

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