PHP: Is it bad practice to use an unset variable? - php

For example, if I want to use the code:
$foo = $_POST['foo']. $_GET['foo'];
to get a value whether passed by POST or GET, is this acceptable or bad practice?

Don't see anything in your answer which is to be unsetted, though you can use $_REQUEST['foo'], as that will consider $_POST as well as $_GET but again, your code will be dirty, say for example I tweaked the method value, for login form, users can easily attack your website...
So be wise, use $_GET[] and $_POST[] instead of using loose $_REQUEST[]
If for any means, you are using $_REQUEST thank make sure you use conditions to check whether the request is GET or POST using $_SERVER['REQUEST_METHOD']
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
//Do something
}

I would go with:
$foo = isset($_REQUEST['foo']) ? $_REQUEST['foo'] : null;
More at: http://php.net/manual/pt_BR/reserved.variables.request.php

to get value whether passeb by POS or GET use this
$foo = $_REQUEST['foo'];

If you configure your development server PHP to throw all warnings, you will find out.

why are you using . operator, if i am not wrong this would concatenate the result, as the above suggested using $_REQUEST would be the better approach.

Yes, it's terrible. There are two problems:
It will raise a warning
Concatenation is not suited for this use case
If you want to get a key from either $_POST, or $_GET, and you don't care which one the key is present in, you can use the $_REQUEST superglobal with the following idiom:
$var = isset($_REQUEST['foo']) ? $_REQUEST['foo'] : null;
$_REQUEST is the union of $_GET and $_POST.

Related

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

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.

What is the benefit of using filter_has_var() over isset()

I'm a little confused with the benefit of using filter_has_var($_POST['id']) over isset($_POST['id']).
Can Somebody please tell me if it's simply an alias function?
Not alot ;) According to the manual page for filter_has_var one user finds filter_has_var a little quicker. Also worth noting... filter_has_var isn't working on the live array ($_POST) but on the actual provided input... if you ever add/remove/update what's in that array you won't see those changes with a filter_has_var call (while isset will reflect the current state)
By the way the usage is filter_has_var(INPUT_POST,"id");
Update: Perhaps worth mentioning, filter_has_var was introduced in PHP 5.2.0 (somewhat new) while isset has been around for all of PHP4+5. Most servers keep up to date on this, but isset will always work (no one still runs PHP3 do they?)
First of all, it's not
filter_has_var($_POST['id'])
It's
filter_has_var(INPUT_POST, 'id')
Secondly, it doesn't actually query the $_POST superglobal. It analyzes the request parameter that came in with the request, so it's a better method to use in case $_POST gets dirtied in some way by the PHP script.
I think you mean filter_has_var(INPUT_POST, 'id') over isset($_POST['id']).
There is a small difference in that isset returns false if $_POST['id'] is NULL; you'd have to use key_exists('id', $_POST) to have similar behavior in that regard.
Besides that, the only difference is that filter_has_var doesn't consider modifications to the $_POST array (see this comment).
Function doesn't check live array
<?php
$_GET['a'] = 1;
echo filter_has_var(INPUT_GET, 'a') ? 'Exist' : 'Not exist';
will print Not exist

$var instead of $_GET['var'] in PHP?

Ok I cannot remember the details on this but on some servers you can use
$var instead of $_GET['var'] to access a variable in the URL, I know this is BAD but I can't remember why it is bad?
I think you mean Register Globals.
You shouldn’t use them because you cannot distinguish the source of that variable values since they can come from any source of the EGPCS variables (Environment, GET, POST, Cookie, Server).
So if you have a the $var, you cannot say if the value is either from $_ENV['var'], $_GET['var'], $_POST['var'], $_COOKIE['var'] or $_SERVER['var'].
The feature is called Register Globals and it allows people to inject variables into your code. See the documentation for examples; here's one:
<?php
// define $authorized = true only if user is authenticated
if (authenticated_user()) {
$authorized = true;
}
// Because we didn't first initialize $authorized as false, this might be
// defined through register_globals, like from GET auth.php?authorized=1
// So, anyone can be seen as authenticated!
if ($authorized) {
include "/highly/sensitive/data.php";
}
?>
You can use that if your server has register_globals set to 1 (or true) on the php.ini file.
At some point, this started to be off by default, and applications started to break, which is a reason why this is a bad practice.
You can see a list of php.ini variables here.
It's also bad because you can confuse yourself with the way that PHP will scope your variables. You may wind up overwriting data if you aren't careful. Also, using $_GET is much clearer as to what you are attempting to accomplish.
Because letting people inject values into arbitrary variables is a very bad thing. You could be storing anything there and they could overwrite some value that compromises your security. Remember to use isset to check that a value has been set before trying to use it.
It's bad because if you're not careful to initialize every variable before you use it (something that PHP won't force you to do), people can easily cause your code to do Very Bad Things with a request as simple as /myapp/index.php?admin_privileges=1.
The setting is called REGISTER_GLOBALS and it was discussed here:
Why is REGISTER_GLOBALS so bad?
If you can do that, then "register_globals" is turned on. This is bad because you won't know where a variable came from, and it mixes your variables with the ones any user can inject via the URL. Read more here: http://www.php.net/manual/en/security.globals.php
Once you get used to using $_POST, $_GET, etc your code's purpose will be easier to read and much, much easier to maintain.
Register globals would work but it's going to go away in a future version of PHP. Not to mention that it really is wrong to have it enabled.
You can use extract() for a more controlled behavior. It will extract the keys from an array (in this case, $_GET) into the local context as variables. You can give them a common prefix so that they don't collide with your existing variables. And you can filter the array beforehand to make sure you're only getting the expected variables.
int extract( $var_array [, $type = EXTR_OVERWRITE [, $prefix ]] )
Import variables from an array into the current symbol table.

Categories