$_REQUEST
$_REQUEST is a superglobal that combines values from $_GET, $_POST, and $_COOKIE into a single associative array. On the surface it looks convenient — one array to read no matter how the data arrived — but that convenience is exactly why professional PHP code tends to avoid it.
How the merge actually works
The contents of $_REQUEST are not fixed by the language; they depend on the request_order directive in php.ini, which lists which sources to merge and in what order. The default in most distributions is "GP" (GET then POST), but some configurations also include cookies ("GPC"). Whichever source is listed last wins when the same key exists in more than one place.
A key present in more than one source
<?php // Suppose the URL is /profile?id=1 // and the form also submits a hidden field named "id" with value 2, // with request_order = "GP" in php.ini echo $_GET['id']; // 1 echo $_POST['id']; // 2 echo $_REQUEST['id']; // 2 - POST came later in request_order, so it wins
1 2 2
Why this is discouraged in professional code
$_REQUESThides where a value actually came from, which makes bugs harder to trace when the same key exists in the URL, a form field, and a cookie at once.Its exact contents depend on a server configuration setting (
request_order) that your code has no control over and that can differ between environments.It blurs the GET-vs-POST distinction that exists for a reason: idempotent reads versus state-changing actions.
Because a cookie can sometimes be included in the merge, an attacker who can set a cookie may be able to override a value you expected to come from a trusted form field.
What to write instead
Explicit is better than $_REQUEST
<?php
// Instead of this:
// $id = $_REQUEST['id'] ?? null;
// Be explicit about the expected source:
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$id = $_POST['id'] ?? null;
} else {
$id = $_GET['id'] ?? null;
}