Say I have a form:
<form action="form.php?redirect=false" method="post">
<input type="hidden" name="redirect" value="true" />
<input type="submit" />
</form>
On form.php:
var_dump($_GET['redirect']) // false
var_dump($_POST['redirect']) // true
var_dump($_REQUEST['redirect']) // true
How do I get the injected query string parameter to override the $_POST value so $_REQUEST['redirect'] will = false ?
If you want to change precedence of $_GET over $_POST in the $_REQUEST array, change the request_order directive in php.ini.
The default value is:
request_order = "GP"
P stands for POST and G stands for GET, and the later values have precedence, so in this configuration, a value in the query string will override a value passed by POST in the $_REQUEST array. If you want POST to override GET values, just switch them around like so:
request_order = "PG"
You'll need to restart the webserver/php for that to take effect.
(Edited to use the more appropriate request_order as Brad suggested, rather than variables_order)
See the request_order directive in PHP.ini.
Really though, you should be explicitly using the superglobal that you specifically want. Otherwise, you cannot rely on consistent behavior from system to system, and then your variables can be accidentally overwritten.
See the request order parameter of PHP. Here you can set whether the array fills post, get, cookie or any combo thereof.
$_REQUEST['redirect'] = $_POST['redirect'];
or
$_REQUEST['redirect'] = $_GET['redirect'];
depending on what you want
If you meant false at that last line there, and want $_REQUEST to still have data from both POST and GET data, and don't want to mess with the config, use this:
$_REQUEST = array_merge($_POST, $_GET);
I just wanted to add in #Chris Hepner 's answer, that as he said:
"the later values have precedence",
later being the letter P than G, and so it means that the POST values have precedence and that POST values overwrite the GET values.
A code example:
<?php
echo ini_get('request_order')."\n";
echo ini_get('variables_order')."\n";
echo var_export($_REQUEST,1);
?>
Results in:
EGPCS
array (
'abc' => '5',
'fed' => '2',
'cde' => '8',
...
)
I added this comment for others looking for information on this
Related
the INPUT_POST Parameter of the PHP filter function filter_input_array() e.g. in
filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
seems to overwrite any modification applied to the superglobal $_POST.
test:
<?php
// 1.
$_POST['abc'] = '123';
var_dump($_POST);
// 2.
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
var_dump($_POST);
?>
output:
after // 2. your $_POST will be empty (as the initial POST was empty)
index.php:4:
array (size=1)
'abc' => string '123' (length=3)
index.php:8:null
so be sure, to put
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING, true);
on the top of your scripts!
Q: did anyone alse notice that behaviour - or did I made an error in reasoning?
Possible Answer: Data are taken from superglobal $_REQUEST an not from $_POST
There is no direct connection between $_POST, and INPUT_POST.
The latter only specifies that filter_input_vars should get the data to filter from the same source as was used to fill $_POST initially. Later manipulation of $_POST does not change what POST data was send to the script originally.
You can easily verify this by setting up a little form that posts a hidden input field to your script. Then add an additional entry to $_POST in that script, as you did in your example above. You will see that filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING) returns an array that contains the entry for the hidden field, but not one for the entry you added to $_POST manually.
That http://php.net/manual/en/filter.constants.php describes INPUT_POST as “POST variables” and links to the description of $_POST might be a little bit misleading here, granted. But to be fair, it says POST there, and not $_POST.
so be sure, to put
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING, true);
on the top of your scripts!
I would not really recommend that. Every PHP developer will assume that $_POST contains unfiltered data. As soon as you f.e. start using 3rd-party modules, that might lead to trouble.
Leaving $_POST as it is, and using a separate variable to hold your filtered POST parameters, is the better way to go IMHO.
Your variable $_POST contains null after that function is executed and assigned to $_POST. From the PHP Manual, null may be returned because the resource on which the function is supposed to work is not defined.
I believe you should investigate either the integrity of your variables or your use of that function.
PHP has list of reserved variables, visit here.
If i use one of the reserved keyword as my variable, it is working for me.
<?php
$_GET = 10;
echo $_GET;//10
?>
Please correct me, if my understanding is wrong?
"Predefined" is not the same as "reserved". PHP gives these variables default values, but you can still use their names for your own purposes. But you shouldn't, since it's poor style.
If you pass GET data into that file like http://example.com/example.php?id=1
Then it will conflict with your $_GET variable..
$_GET = Array { [id] => 1 }
After your declaration the value will be changed as
$_GET = 10
It will overwrite the old value..
I can't imagine a situation where you would want to do what you're suggesting.
in the case of $_GET, $_SESSION, they are arrays where you can assign a key value pair at will, that's what they're designed for.
$_SESSION["UID"]=username;
for example
$_GET is not a reserved variable.
$_GET is an associative array of variables passed to the current script via the URL parameters. Also is a superglobal. Read the documentation to learn how to use it
You should use like
$_GET['key']=10;//good
Doing
$_GET =10;//bad
will overwrite the value and it works but is a very wrong way to use a superglobal and they were not designed to work that way
I have a bunch of values from checkboxes that are boolean. Al I want to do is set them to yes if they are 1 and no if they are 0.
My code fails, looks ok to me?
$item = $form_state['values']['item1'] == 1 ? 'Yes' : 'No';
If your checkboxes have value attribute equal to 1, it should be OK:
<input ... type="checkbox" value="1" />
If you have not set these values or in all the cases you may just check, if they exists in $_GET or $_POST array (assuming $form_state is taken from there):
$item = isset($form_state['values']['item1']) ? 'Yes' : 'No';
The above example, should works for you. Keep in mind radio buttons and check boxes will not be set in $_GET or $_POST if they are not selected, at all, which also may generate Notice or Warning, if trying to access non-existing index.
In older versions of php you might need to use $_REQUEST.
I made a script before, that worked completely fine in PHP 5.2. But when recently going over to my friends server (version PHP 4.4.9), I noticed some actions didn't work the way they should. The outcome of what the checkboxes returned came out crazy...
This is the code I'm using:
For the form:
<input type="checkbox" value="Box1" name="BoxGroup[]" />Box1
<input type="checkbox" value="Box2" name="BoxGroup[]" />Box2
<input type="checkbox" value="Box3" name="BoxGroup[]" />Box3
For the action script:
if($_POST['BoxGroup'] == true){ // If one of the checkboxes were checked...
foreach($_POST['BoxGroup'] as $value){
$BoxGroup .= ", ".$value; // Make the array into a string
}
$BoxGroup = substr($BoxGroup,2); // To skip ", " from the beginning of the $BoxGroup variable
}
Now, what this script does, is; when a user sends the form, it checks if one of the checkboxes were checked, and if so, it will make a string, like so: "value, value" etc.
I insert these values to my database. When I preview what's been submitted to the database on a page, I get "ray / value / value", -- so only "ray" (as in "Array") was passed for the first box it seems.
Unfortunately, I can not update the server's version of PHP, since both the system operator and I, don't have the root password to it (I know it's crazy).
So what do I do?
implode(', ', array_keys($_POST['BoxGroup']))
I'd recommend the implode function:
http://php.net/manual/en/function.implode.php
So your whole operation will getting a bit shorter and easier to overview.
cheers
The other comments regarding implode are good advice, but I don't see how it fixes your problem. (Well, it actually could, if you initialize the variable to the return value of implode, but that doesn't fix the core issue here.)
Initialize $BoxGroup properly. I bet $BoxGroup = 'Array'; before the loop even runs... probably due to register_globals turned on. Eeeek, disable that.
In .htaccess:
php_flag register_globals off
To elaborate, I assume that if you did a var_dump($BoxGroup), you'd see that it already contains those values thanks to register_globals. The array gets treated as a string 'Array' when you concat it with another string.
It may sound strange, but in my PHP application I need to check if the same variable name has been declared more than once in the query string or POST variables, and return an error value if this is the case. If my application doesn't return an error in this case, it fails a compliance check.
When accessing vars using $_GET, $_POST, etc, PHP only returns the last value given for each variable name. I can't find a way to tell if any variable appeared more than once.
I simply need to find out if the query string or the variables in the POST body contained the same variable name more than once, whatever the values.
Example
My application is supposed to return an error for this query string:
verb=ListIdentifiers&metadataPrefix=oai_dc&metadataPrefix=oai_dc
Note that "metadataPrefix" is defined twice.
My application should not return an error for this query string:
verb=ListIdentifiers&metadataPrefix=oai_dc
POST Requests
$input = file_get_contents('php://input');
(Or $HTTP_RAW_POST_DATA (docs))
GET Requests
$input = $_SERVER['QUERY_STRING'];
Processing
explode('&', $input) and maintain an array - $foundKeys - of keys (the part of each item from explode() before the = character). If you hit a key already defined in $foundKeys, throw the error.
For GET data, check out $_SERVER['QUERY_STRING']. But for POST data, you'll need to read the raw POST data from the php://input stream.
So something like this:
// GET data:
$raw = $_SERVER['QUERY_STRING'];
// Or for POST data:
$raw = file_get_contents("php://input");
if (substr_count('&'.$raw, '&metadataPrefix=') > 1)
die('Error');
print_r($raw); //post vars
PHP $_POST will always set only one value per variable unless the request variable name ends with [].
If you have no control over the variables that are sent, you may try using $_SERVER['RAW_HTTP_POST_DATA'] to get the original POST request data before parsed, then you can use the parse_str() function to parse that string.
Just be careful that PHP configuration may have disabled setting the RAW_HTTP_POST_DATA value. In that case, you cannot do anything to solve your problem.
Not completely foolproof but this might work
$occurrences = substr_count($_SERVER['QUERY_STRING'], 'metadataPrefix=');
If you expect multiple values named the variable with square brackets in the end. This way you get an array for that variable. If multiple values are set, the array will have multiple entries.
<input type="checkbox" name="my_var[]" value="a">
<input type="checkbox" name="my_var[]" value="b">
$_POST['my_var'] will be an array with either 'a' or 'b', both, or none depending on the checkboxes used.