Checking global arrays in PHP - php

I have a question and hope you have the answer to it. When submitting data from one form to the next page for processing, is it better to check the global array as a whole e.g.
isset($_POST)
or
isset($_POST['value'])
My question is applicable to all global arrays like $_POST, $_SESSION, $_FILES, etc. The reason is that I get a lot of bad handling to deal with caused by checking if certain variables are checked or not.

$_POST and the other superglobals are always defined, so isset($_POST) and such is meaningless (it will always return true).
The second check is what you should use.

isset($_POST) is always true, you need to check at least one key inside $_POST.
If the $_POST['value'] is blank it will be also set so you need to check if that variable isn't empty if($_POST['value'] != '') too

Related

Should I check isset($_GET[...]) when I expect it to always be set?

I was recently placed on a project with some PHP, and I don't know much about PHP. There are a couple instances in the site where upon clicking a button, the user is redirected to another page with some URL parameters. The next page then uses $_GET to get those parameters and move on.
Another issue in the code caused the page to reload the second page without the parameters, so using $_GET would return errors, but with the other issue fixed, I can't think of a reason why the parameters wouldn't be there.
While debugging, I came across advice to always check $_GET using isset(), but theoretically there should never be an instance when those parameters aren't there (otherwise something else is really wrong with the server or the code).
Is it still worth putting in the checks and working out a backup solution, even though there shouldn't be a need for it? I want to make sure I'm not ignoring some other potential issue that I may not be aware of.
It is always good practice+recommended to check your variables before applying any logic.
!empty() is recommended to use instead of isset() because it check both that variable is initialized and have some values too.
In case of array count($array)>0 can be used as a check.
Why to use !empty() check here:- !empty() Vs isset()
If you are expecting or requiring data to be sent via $_GET you should check if it's set. Especially since that data can be easily manipulated. Also like #Alive to Die said !empty() is better.
isset() checks if a variable has a value including ( False , 0 , or
empty string) , but not NULL. Returns TRUE if var exists; FALSE
otherwise. On the other hand the empty() function checks if the
variable has an empty value empty string , 0, NULL ,or False.

isset($_POST) is correct usage or not?

The problem I'm facing is quite common I suppose but I didn't see a single thread in internet.
If I use isset($_POST),
Will it always return true?
Does the response depend on the version of PHP I use?
Is $_POST is a variable? (it's a super global 'variable' after all). Because in php.net documentation, it is mentioned
isset() only works with variables as passing anything else will result in a parse error.
Will it always return true?
Yes, even if the page was opened using GET method or nothing was POSTed.
Does the response depend on the version of PHP I use?
No it does not (not sure about very old versions of PHP).
Is $_POST is a variable?
Yes
isset() only works with variables as passing anything else will result in a parse error.
This is explicitly mentioned in the manual so that people do not try to do cheaky stuff. These won't work for example:
function getVarName() { return '_POST'; }
isset(getVarName());
isset('$_POST');
Now, why would you want to check if $_POST is set. Perhaps want to check if a certain variable (e.g. email) was posted, in that case you need to check:
isset($_POST["email"])
isset($_POST); will always return true. If you want to check if it contains something use empty($_POST);
Does the response depend on the version of PHP I use?
No
Is $_POST is a variable ?
Yes
Whether or not you posted any data $_POST will always be set as an array. What you are probably looking for is the empty() method to see if any data was actually posted, like:
if(!empty($_POST)) {
// POST data was set
}
I would recommend using one of the following:
if($_POST){
}
if(!empty($_POST)){
}
1, Will it always return true?
isset($_POST) will always return true. If $_POST is empty it will return false.
2, Does the response depend on the version of PHP I use?
I'm not sure about versions below 4.* but the response has always been the same.
3, Is $_POST is a variable?
Yes, it is considered a superglobal like: $GLOBALS, $_SESSION, $_POST, $_GET
Will it always return true?
Yes it would always be true
Does the response depend on the version of PHP I use?
No tested on PHP 4.3.0 - 5.4.10
Is $_POST is a variable?
Definitely Yes
Better way to validate $_POST is to use empty
Isset()
return true only if it contains some value (it can be Zero 0).
If it doesn't have any value then it returns false.
If you want to prevent from (0) use
if(isset($_POST) && $_POST)
This will be true if only it has non-zero value
$_POST is global array
Response doesn't depend upon the version of PHP

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

PHP filter_has_var vs empty?

i know that empty is a bit faster then isset, but filter_has_var is a bit faster then isset (in php.net it written) so what is faster empty or filter_has_var ?
filter_has_var() might be useful if the superglobals have been purged for some reason, because it checks the original input data, not $_GET, $_POST, $_ETC.
For example:
$_GET["injected"] = 123;
var_dump( filter_has_var(INPUT_GET, "injected") ); // false
// or the other way round
While you can overwrite the variable, the filter extension accesses a separate copy. And INPUT_GET will not alias to the $_GET superglobal.
Apart from that another reason is to use it for unification. If you use filter_var extensively, than a ruleset would be more fond of using filter_has_var() over isset().
But don't use one or the other because of any silly performance reasons.
filter_has_var and empty are two totally different functions that do totally different things. You would not want to swap the use of these two functions.
empty is actually a language construct that checks if a variable is considered empty to PHP: for example null, array() or '' are considered empty.
filter_has_var simply checks one of the PHP superglobals: $_GET, $_POST, $_SERVER, $_ENV or $_COOKIE to ensure that a variable was passed with a request. This function will still return true if the var is empty.

I'm confused about the flow of $_POST[] variables and regular variables

I have a simple form I created, and in it I have the following checkbox:
<input type="checkbox" name="test">
Note: this form is being submitted to itself.
Above the form, I have the following PHP:
if (empty($_POST['test'])) {
$thevalue = 0;
} else {
$thevalue = 1;
}
var_dump($thevalue);
When I process the form, I get what I would expect. If I check the box and submit, I get int(1) if I leave it unchecked I get int(0).
In the first line of my PHP code, I wanted to replace $_POST['test'] with some simple variable.
So I added the following line above my code:
$simplevar = $_POST['test']
I then replaced the condition in my if statement to be empty($simplevar)
But when I submit the form, I get a "Notice: Undefined index:" error message
Why is this happening?
Assuming it's possible to achieve what I was after (i.e. insert $_POST into $simplevar), how might I go about it?
Thanks in advance for your help!
PS: I may have a follow up to this question, but didn't want to clutter things by jamming it all in here.
Thanks again... oh, and Merry Christmas! ;-)
This happens because when you don't check the checkbox, the browser does not send any value to server for that control when the form is submitted. Because of this, $_POST['test'] is not defined, and you tried to use it without a check as to whether it existed, so you get a warning. One of the checks that empty() does is to see whether the value is set. So, when you use the $_POST keys directly in empty(), you don't get an error, but when you try and use it in an assignment without this check, you will get the error.
You can do roughly what you want to do, you just have to change the logic slightly. If you do:
$simplevar = !empty($_POST['test']);
// You could also do
// $simplevar = isset($_POST['test']);
if ($simplevar) {
// The box was checked
} else {
// The box was not checked
}
...it will do what you want without the error. Using this approach, $simplevar always holds a boolean indicating whether or not the box was checked.
When a checkbox is unchecked, it's not added to the $_POST array as a key, which is why $simplevar = $_POST['test'] returns the error you posted. Using empty() gets past this problem by empty() handling errors better (well, silently at any rate).
You haven't specified whether you get that error when the checkbox is checked or not, but the above explanation is the only one I can give. If you're unsure, try doing print_r($_POST) to see what $_POST actually contains.
A solution to your problem would be to use a ternary expression to handle the error a little better:
$simplevar = isset($_POST['test']) ? 0 : 1;
This will assign 0 to $simplevar if $_POST['test'] isn't set (checkbox isn't checked), or 1 otherwise.
Do make sure all your form processing code is put inside
if(!empty($_POST)) {
// Code
}
So that it's not executed every time the page loads, otherwise your error will show every time.
Checkbox values are only transmitted if the checkbox was checked. This means that unchecked checkboxes won't appear in the $_POST array.
A way to suppress the notice from PHP is to use a reference instead of a variable:
$simplevar =& $_POST['test'];
if(empty($simplevar)) $thevalue = 1;
else $thevalue = 0;
That's expected behaviour. If you are assigning the variable like this:
$simplevar = $_POST['test'];
Then the $_POST variable might be absent. The Zend runtime then assigns the NULL value, but gives you a useful debug hint, should that not be what you wanted.
When you used empty() before, the check for variable existence was built in. empty() is a language construct. Like isset() it's often used to eschew such notices. The cumbersome syntax to emulate such language behaviour is:
$simplevar = empty($_POST['test']) ? NULL : $_POST['test'];
The language built-in for is:
$simplevar = #( $_POST['test'] );
Now, I will get roasted for mentioning it. (Using # is useful if you want to bring the debug notices back at some point, while the empty and isset constructs eternally suppress them.)
First, you should always check that variables in $_POST, $_REQUEST, and $_GET are set before attempting to use them. Always handle the condition where they are not set even if you simply output an error.
Because the error is an undefined index it seem the error is in test not being set in $_POST, though that doesn't make a lot of sense. I would add a check, maybe an echo or var dump to check $_POST. If it is set the other problem could be an issue with scope. $_POST is something called a super global which makes it available in any scope. Variables you set you may need to make global by defining them as such if you want to access them across scopes.

Categories