I'm facing this dilemma, basically I want to create an error object if a certain task isn't met. Now to understand what I've got to send back to the user, I need to check to see if that error object is either empty or has data. The issue is this:
$obj = new stdClass();
var_dump(empty($obj)); // returns false
As you can see in this example, it's returning false instead of true as it's empty.
$o = new stdClass();
$a = array();
var_dump(empty($o));
var_dump(empty($a));
Example
This works perfectly fine for an array, but does anyone know why this is happening for objects?
I've read answers like this which state to cast it as an array, but my question is this:
Why does it return false when it's empty? What is the logic behind it?
If I wanted an array, I would've started with that.
From php.net:
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)
Every object you create won't be "empty".
Related
I thought I knew everything about php until I bumped into this:
$foo = 'hello';
isset($foo['a']); // returns false - OK
isset($foo['a']['b']; // returns false - OK
isset($foo['a'][0]); // returns true! WTF?!
Could anybody explain me the result of the 4th line? Tested with php 5.5.36.
Well, the question is somewhat misleading, because isset returns true for any variable that is not null. Since $foo is a string, and not an array, $foo["a"] gives an Illegal string offset warning. PHP assumes that you meant to cast "a" as an integer offset and does that implicitly, turning $foo["a"] into $foo[0] which gives you the string "h" (the first offset of the string). Since the return value is another string the expression becomes "h"[0], which is just "h" again.
So in other words, $foo["a"][0] where $foo = "hello" is the same thing as $foo[0][0] which gives us "h".
But as far as non-existing array keys, isset would definitely return false since a non-existing key leads to a non-existing value which is implicitly null.
multi-select lists are named thusly: <select name="list[]" multiple>
When the form is submitted, if the user hasn't selected anything, then I wish to ignore that input.
I'm trying:
if (isset($_POST["list"]))
and
if (count($_POST["list"]))
but that throws an error, presumably because PHP doesn't receive the array unless at least one item is selected. If the user does select at least one of the options, there is no error.
The complaint is that "list" is a nonexistent index.
I need at least one of these solutions:
To force the submit to send an empty array so the index in $_POST will be legal, OR
I need to test for the existence of the index variable without throwing an error.
I'm also trying to use the try-catch syntax but having issues with that as well. I have a separate post open for that issue.
any suggestions on detecting a listbox with nothing selected?
Thanks,
Dana
Try using empty():
if (!empty($_POST["list"])) {
For your case, !empty() would be TRUE if list[] is set and if it has at least one value.
From the documentation:
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)
This question already has answers here:
Evaluate object to a boolean
(6 answers)
Closed 9 years ago.
I made an object that was suposed to represent an array, but with a few methods. So I made it implement the native interfaces: IteratorAggregate and Countable. That way you can foreach and count it. So far so good.
But now I want it to evaluate like an array as well. So, if count($object) is zero, if($object) is suposed to evaluate as false. Is there a Comparable interface or something?
Use type Juggling.
You can assign the expected type of your var.
$object = count ( $object );
$object = (array) $object;
The same way, if you want to assign to your variable some other type, here is list of possible values:
(int)
(bool)
(float)
(string)
(array)
(object)
(unset)
(binary)
Also check this this Comparable interface.
The documentation shows everything that evaluates to false:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
As of this list an object will never be considered as false. So the only way is to cast the value of count() to boolean using (bool) if you need to do a strict comparison as pointed out in Tomi Sebastián Juárez's answer.
What I'm trying to do:
treat the POST data from a multi-select input with the array_diff() function
Initial code:
$relations_to_delete=array_diff($selectedEnjeuxMetiers,$this->request->data['EnjeuxMembership']['EnjeuxMetier']);
Probem: It was not working when nothing was selected in the multiselect input
Current solution:
if(!empty($this->request->data['EnjeuxMembership']['EnjeuxMetier'])){
$relations_to_delete=array_diff($selectedEnjeuxMetiers,$this->request->data['EnjeuxMembership']['EnjeuxMetier']);
}else{
$relations_to_delete=$selectedEnjeuxMetiers;
}
This solution works. !=null was not working, nor gettype()=="array"
Question: Could anyone could explain why the if(!empty()) test is necessary, and if the problem comes from the POST data or the array_diff function?
EDIT: It works with gettype()=="array". The problem was that the type when there is no data is not an empty array but an empty string.
Additional info: CakePHP docs about the way Post data are converted to an array.
With the function "empty()", the variable is considered empty if it is equal to:
"" (an empty string)
0 (0 as an integer)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
var $var; (a variable declared, but without a value in a class)
The value should be coming "" or NULL when no option is selected.
The problem was that the type when there is no data is not an empty array but an empty string.
I know there is array_key_exists() but after reading the documentation I'm not really sure if it fits for this case:
I have an $array and an $index. Now I want to access the $array, but don't know if it has an index matching $index. I'm not talking about an associative array, but an plain boring normal numerically indexed array.
Is there an safe way to figure out if I would really access an $array element with the given $index (which is an integer!)?
PHP may not care if I access an array with an index out of bounds and maybe just returns NULL or so, but I don't want to even attempt to code dirty, so I want to check if the array has the key, or not ;-)
You can use either the language construct isset, or the function array_key_exists : numeric or string key doesn't matter : it's still an associative array, for PHP.
isset should be a bit faster (as it's not a function), but will return false if the element exists and has the value NULL.
For example, considering this array :
$a = array(
123 => 'glop',
456 => null,
);
And those three tests, relying on isset :
var_dump(isset($a[123]));
var_dump(isset($a[456]));
var_dump(isset($a[789]));
You'll get this kind of output :
boolean true
boolean false
boolean false
Because :
in the first case, the element exists, and is not null
in the second, the element exists, but is null
and, in the third, the element doesn't exist
On the other hand, using array_key_exists like in this portion of code :
var_dump(array_key_exists(123, $a));
var_dump(array_key_exists(456, $a));
var_dump(array_key_exists(789, $a));
You'll get this output :
boolean true
boolean true
boolean false
Because :
in the two first cases, the element exists -- even if it's null in the second case
and, in the third, it doesn't exist.
You can easily use isset():
if (isset($array[$index])) {
// array index $index exists
}
And as you have suggested, PHP is not very kind if you try to access a non-existent index, so it is crucial that you check that you are within bounds when dealing with accessing specific array indexes.
If you decide to use array_key_exists(), please note that there is a subtle difference:
isset() does not return TRUE for array
keys that correspond to a NULL value,
while array_key_exists() does.
That's exactly what the array_key_exists is for. It works on both numerical and string indexes.