PHP is it OK to try access an associative array if you are unsure the key exists? - php

Is it OK to rely on PHP's behaviour if a key is not in the array? Which is:
Attempting to access an array key which has not been defined is the same as accessing any other undefined variable: an E_NOTICE-level error message will be issued, and the result will be NULL.
For instance if I do not know $_POST contains certain keys is it OK to just try? I want the result to be null anyway. Or is there a better way?

Since you should always develop with error reporting turned on, you want to avoid triggering avoidable errors so as to keep error reporting useful to you. As such, no, it's not okay. Use isset or empty. For a more in-depth excursion into this topic see The Definitive Guide To PHP's isset And empty.

You can use isset() to check if it exists and if so do stuff.
if(isset($_POST["key"])){// do stuff}

You should use isset() or empty() to test it.

If it is necessary to check if a key exists even if it the key is set to null then array_key_exists(mixed $key , array $search) will be usefull. But it is very slow compared to isset(). So isset() shall be used if you check for a key that is in the array and not null.

isset()function can save you from the warning of index not found by checking for it first
isset($_POST['notSure']) ? $var= $_POST['notSure'] : $var = null;

Related

Replacing array_key_exists() with isset() in PHP

Knowing the differences of array_key_exists() and isset() in PHP, I see a lot of advocates on the web suggesting for replacing array_key_exists() with isset(), but I am thinking is it safe to do so?
In one project, I have the value of $var submitted by users. The value can be anything, even NULL or not set at all. I want to use !empty($var) to check if $var holds a non-empty value, but I understand that using !empty($var) alone is dangerous since if $var isn't pre-defined, PHP will throw an error.
So I have isset($var) && !empty($var) for checking whether $var holds a non-empty value.
However, things get complicated when I have a value stored in an assoc array. Compare the followings, assuming array $arr always exists but the key foo may or may not exist in $arr.
// code snipplet 1
$arr = array();
echo isset($arr['foo']);
// code snipplet 2
$arr = array();
echo array_key_exists('foo', $arr) && !is_null($arr['foo']);
Code snipplet 2 will always work but it seems clumsy and harder to read. As for code snipplet 1, I had bad experience... I wrote something like that before in the past on a development machine. It ran fine, but when I deployed the code to the production machine, it threw errors simply because key didn't exist in array. After some debugging, I found that the PHP configs were different between the development and the production machines and their PHP versions are slightly different.
So, I am thinking is it really that safe to just replace array_key_exists() with isset()? If not, what can be of better alternatives of code snipplet 2?
In one project, I have the value of $var submitted by users.
How does that work? Users shouldn't be able to set variables. They should be able to, e.g., submit form values which end up in $_POST. I repeat, they should not be able to directly create variables in your scope.
If "users" here means some sort of plugin system where people write and include PHP code… then you may want to think about defining a more stable interface than setting variables.
The value can be anything, even NULL…
Not if it's a value submitted through HTTP. HTTP has no concept of null. It's either an empty string or doesn't exist at all.
using !empty($var) alone is dangerous since if $var isn't pre-defined, PHP will throw an error
That is wrong. empty specifically exists to test a variable against false without throwing an error. empty($var) is the same as !$var without triggering an error if the variable doesn't exist.
So I have isset($var) && !empty($var) for checking whether $var holds a non-empty value.
See Why check both isset() and !empty(). (Spoiler: it's redundant.)
echo isset($arr['foo']);
echo array_key_exists('foo', $arr) && !is_null($arr['foo']);
These both do exactly the same thing. isset returns true if the value exists and its value is not null. The second line returns true if the array key exists and its value is not null. Same thing.
I had bad experience...
You'd need to be more detailed about that, since there should be no caveat to isset as you describe it.
See The Definitive Guide To PHP's isset And empty and Difference between isset and array_key_exists.

Calling isset() vs. returning undefined index

I have code that is used very extensively which fetches an array from another method, and sometimes returns the first element of that array. Given that null is an acceptable return value for the function, is it worth the performance overhead of calling isset() on the array index (or checking the array length, etc), or is it better to just return the non-existant index (warnings aside). What are the advantages of calling isset() aside from preventing the warning.
The example below is simplified, the real function doesn't just get the first element of the array.
Return index which may not exist:
function get_array_element(){
$array = get_array(); // function that returns array
return $array[0]; // return index 0 which may not exist
}
Versus checking if index is set:
function get_array_element(){
$array = get_array(); // function that returns array
return (isset($array[0]))? // check if index 0 isset() else return null
$array[0] :
null;
}
Throwing a notice when accessing an undefined index -- in theory -- should alert you for typos in key names. In practice, if you’re using isset first, you probably just copied the key name there. Or used a numeric index. Or a constant.
On the other hand, in most cases you’re accessing an index withour caring wether it’s set or not -- and in this scenario, using isset is just anoying. A lot of languages lets you just retrieve any index without warnings, Javascript for example: just returning an undefined.
So I would advice to ignore the notice. Not all of them, because in some cases there really are helpful, so keep them turned on in development, but silence such array access by using #. Yes, it is ugly, but does its job:
return #$array[0];
Or in simple cases, maybe other solutions fit?
return array_shift($array);
Calling isset inside that function is semi-pointless because you are returning null if it doesn't exist, but null will be returned from $array[0] regardless of whether you use isset of not.
If it only throws an E_NOTICE then I wouldn't worry about it, just check for get_array_element() == null.

isset or !empty for $_GET[var]

i recently had to do a "test" for a job, and i got feed back saying that this statement was incorrect:
$images = $flickr->get_images(5, !empty($_GET['pg']) ? $_GET['pg'] : 1);
The "supposed" error was generated via the ternary operator on the first time the page was loaded, as there was no "?pg=1" (or whatever) passed via the query string.
The feed back said i should have used isset instead. I have looked at various posts both here (question 1960509) and blogs, but cannot find any definitive answer.
Is this really an error? How can i replicate this issue? do i need to put on E_STRICT or something in my php.ini file? Or might this be due to an older version of php?
Note: please don't tell me about how i should validate things.. i know this... it was a test to just see if i could use the flickr api calls.
This is perfectly fine. empty is not an actual function, it's a language construct. It does not issue a warning if a variable is not set (in that case the variable is considered empty, thus the 'function' returns TRUE just as you want), and additionally it checks for empty or zero values.
You could see empty as a normal isset check with an additional loose comparison to FALSE:
empty($var) === (!isset($var) || $var == FALSE)
$images = $flickr->get_images(5, (isset($_GET['pg']&&($_GET['pg']))) ? $_GET['pg'] : 1);
without isset you'll get error so combine them
I'd use
$images = $flickr->get_images(5, array_key_exists('pg', $_GET) ? $_GET['pg'] : 1);
Combine with !empty($_GET['pg']) if needed (i.e. array_key_exists('pg', $_GET) && !empty($_GET['pg'])), but array_key_exists is the intended function for this job.
I think in a situation like this isset is the correct function to use as it is checking the existence of the array element rather than checking if the value of the element has been set. As Martin notes, the best thing to do here is combine them as this will only check the value if the element exists, meaning that the error will not occur on the first page load.
Also, I think this will only give a warning if E_NOTICE is on (or perhaps E_WARNING as well)
The reason you would get an error is because the empty function is designed to check the value of an existing variable, whearas isset() is designed to tell you whether a variable has been instantiated, however because empty() is a language construct technically it doesn't throw an error or create a warning so most people don't see the difference.
From the docs:
empty() is the opposite of (boolean) var, except that no warning is generated when the variable is not set.
isset — Determine if a variable is set and is not NULL. So "isset" is the correct function to use for checking for value is set or not.
More details :http://php.net/manual/en/function.isset.php

Find Element in PHP Array (if exists)

I'm wondering if there is a more elegant way to do this:
$foo = (isset($bar) and array_key_exists('meh', $bar)) ? $bar['meh'] : '';
If I remove the isset part, PHP issues a warning if $bar isn't an array, if I remove the array_key_exists part, PHP issues a warning if the meh key isn't in the array. Is there a more graceful, warning free, way of achieving the same end?
You take exactly the steps required to "secure" code against the warnings you mention.
However, the warnings are there for a reason. Typically it makes more sense to check, if you can prevent situations where the variables you are trying to access are not initialized.
You can reference the key directly. Inside isset it won't even throw an exception if $bar is undefined.
$foo = isset($bar['meh']) ? $bar['meh'] : '';
The difference between array_key_exists and isset is that isset will return FALSE if the key corresponds to a NULL value. In my code above, a NULL value will therefore result in $foo begin the empty string, not NULL. If that is a problem your current approach will be the best.

Undefined index: Error in php script

In a php page I have following code:
if($_REQUEST['c']!="") // I get error on this line itself. Why?
{
$pidis=(int)($_REQUEST['c']);
}
I keep getting Undefined index error.
On Googling I manage to understand that if a page is access without parameters (in URL) which we are trying to access we can get this error/warning. I believe that if a parameter is not defined in the URL it should just return empty instead of giving error/warning message.
I know that it is possible to suppress errors and warning by adding
error_reporting(E_ALL ^ E_NOTICE);
But I do not want to do this.
This same page work just fine on our company's web server but does not work on our clients web server.
Why is this happening?
How to solve this problem?
You are getting that error because you are attempting to compare $_REQUEST['c'] to something when $_REQUEST['c'] does not exist.
The solution is to use isset() before comparing it. This will remove the warning, since the comparison won't happen if $_REQUEST['c'] doesn't exist.
if(isset($_REQUEST['c']) && $_REQUEST['c']!="")
{
$pidis=(int)($_REQUEST['c']);
}
It is an E_NOTICE level error, and your level of error reporting will affect whether the error shows up or not. Your client's server has E_NOTICE level error reporting turned on, which is why it shows up there.
It is a good idea to always develop using E_ALL so that you can catch this kind of error before moving your code to other servers.
Another solution is to use the following:
$pidis = isset($_REQUEST['c']) ? $_REQUEST['c'] : '';
You can also, if you prefer to return a value other than empty, by placing a default value within the final set of single quotes, e.g.
$pidis = isset($_REQUEST['c']) ? $_REQUEST['c'] : 'Default Value';
or return a different variable type, for instance an integer:
$pidis = isset($_REQUEST['c']) ? $_REQUEST['c'] : 34;
Instead of isset() you can also use: array_key_exists().
The difference between both methods is that isset() checks also whether the value of the variable is null. If it is null then isset returns false whereas array_key_exists() returns always true if the key exists (no mater which value). E.g.:
$array = array('c' => null);
var_dump(isset($array['c']))); // isset() returns FALSE here
var_dump(array_key_exists($array['c']); //array_key_exists() returns TRUE
Depending on the context, it is important to distinguish this. In your case I don't think it matters doesn't matter, as (I guess) a request parameter never will be null (except one overwrites it manually).
Use isset($_REQUEST['c']) to test if it exists first.
PHP is giving a notice (which is not an error : it's just a notice) when you are trying to use a variable that doesn't exists, or an array element that doesn't exist.
This is just to help you, and you should not mask those notices : they are here to help you -- for instance, to help you detect typos in variable names.
Before using that array index, if it's not always present, you should test if it's here, using isset :
if (isset($_REQUEST['c']) && $_REQUEST['c']!="") {
// ...
}
Clean way could be :
$pidis = $_REQUEST['c'] ?? null
this is same as checking isset request but shorter.

Categories