In PHP version 7.0 with the default settings.+, $_REQUEST array does not contain cookies.
$_REQUEST — HTTP Request 变量
Note:
"Superglobal"也称为自动化的全局变量。这就表示其在脚本的所有作用域中都是可用的。不需要在函数或方法中用 global $variable; 来访问它。
Note:
Note:
由于 $_REQUEST 中的变量通过 GET,POST 和 COOKIE 输入机制传递给脚本文件,因此可以被远程用户篡改而并不可信。这个数组的项目及其顺序依赖于 PHP 的 variables_order 指令的配置。
In PHP version 7.0 with the default settings.+, $_REQUEST array does not contain cookies.
Warning:
The way $_REQUEST is populated by default can lead to strange bugs because of the unfortunate default setting of the configuration directive 'variables_order'.
Example: In an e-shop you want to display prices based on user preference. User can either switch the currency or the previous selection is used. By defaut, the following code WILL NOT WORK as expected:
<?php
if ($_REQUEST['currency']) # change currency on user request
{
$currency = $_REQUEST['currency']; # use it
setcookie('currency', $_REQUEST['currency'], 0, 'eshop.php'); # store it
}
else # use default currency
{
$currency = 'USD';
}
# display shop contents with user selected currency
echo 'All prices are shown in ', $currency;
# let the user switch currency
echo '<a href="eshop.php?currency=USD">Switch to USD</a>';
echo '<a href="eshop.php?currency=EUR">Switch to EUR</a>';
?>
Regardless of the user choice, the cookie value is used, so unless you change the default 'request_order' or 'variables_order' the $_REQUEST[something] variable is stuck with the cookie value forever regardless of the user 'REQUEST'.
Fix 1:
<?php
ini_set('request_order', 'CGP'); # use previous value (stored in cookie) or new value upon user request
.
.
.
?>
Fix 2:
Be very careful and patient and go with $_GET, $_POST and $_COOKIE instead of the convenient $_REQUEST. Good luck.
To access $_POST, $_GET, etc, use the function filter_input(TYPE, varname, filter) to ensure that your data is clean.
Also, I was brought up to believe that modifying superglobals is a BAD idea. I stand by this belief and would recommend you do too
The default php.ini on your system as of in PHP 5.3.0 may exclude cookies from $_REQUEST. The request_order ini directive specifies what goes in the $_REQUEST array; if that does not exist, then the variables_order directive does. Your distribution's php.ini may exclude cookies by default, so beware.
I wrote a function because I found it inconvenient if I needed to change a particular parameter (get) while preserving the others. For example, I want to make a hyperlink on a web page with the URL http://www.example.com/script.php?id=1&blah=blah+blah&page=1 and change the value of "page" to 2 without getting rid of the other parameters.
<?php
function add_or_change_parameter($parameter, $value)
{
$params = array();
$output = "?";
$firstRun = true;
foreach($_GET as $key=>$val)
{
if($key != $parameter)
{
if(!$firstRun)
{
$output .= "&";
}
else
{
$firstRun = false;
}
$output .= $key."=".urlencode($val);
}
}
if(!$firstRun)
$output .= "&";
$output .= $parameter."=".urlencode($value);
return htmlentities($output);
}
?>
Now, I can add a hyperlink to the page (http://www.example.com/script.php?id=1&blah=blah+blah&page=1) like this:
<a href="<?php echo add_or_change_parameter("page", "2"); ?>">Click to go to page 2</a>
The above code will output
<a href="?id=1&blah=blah+blah&page=2">Click to go to page 2</a>
Also, if I was setting "page" to a string rather than just "2", the value would be urlencode()'d.
<a href="<?php echo add_or_change_parameter("page", "banana+split!"); ?>">Click to go to page banana split!</a>
would become
<a href="?id=1&blah=blah+blah&page=banana+split%21">Click to go to page banana split!</a>
[EDIT BY danbrown AT php DOT net: Contains a bugfix provided by (theogony AT gmail DOT com), which adds missing `echo` instructions to the HREF tags.]
Don't forget, because $_REQUEST is a different variable than $_GET and $_POST, it is treated as such in PHP -- modifying $_GET or $_POST elements at runtime will not affect the ellements in $_REQUEST, nor vice versa.
e.g:
<?php
$_GET['foo'] = 'a';
$_POST['bar'] = 'b';
var_dump($_GET); // Element 'foo' is string(1) "a"
var_dump($_POST); // Element 'bar' is string(1) "b"
var_dump($_REQUEST); // Does not contain elements 'foo' or 'bar'
?>
If you want to evaluate $_GET and $_POST variables by a single token without including $_COOKIE in the mix, use $_SERVER['REQUEST_METHOD'] to identify the method used and set up a switch block accordingly, e.g:
<?php
switch($_SERVER['REQUEST_METHOD'])
{
case 'GET': $the_request = &$_GET; break;
case 'POST': $the_request = &$_POST; break;
.
. // Etc.
.
default:
}
?>