$_REQUEST

Yo Yogesh.M Updated 01 Nov 2026
6 min read ·Lesson 215 of 219

$_REQUEST

What Is $_REQUEST?

In simple terms: $_REQUEST is an array that combines data from several sources — usually the URL query string ($_GET) and submitted form data ($_POST) — into one place. Technically: $_REQUEST is a superglobal built by PHP at the start of each request from $_GET, $_POST, and possibly $_COOKIE. Which sources are included, and in which order they override each other, is controlled by the request_order setting (or variables_order if request_order is empty).

Why It Exists

$_REQUEST was designed for convenience: a script could read a value without caring whether it came from a link (GET) or a form (POST). In practice, this convenience creates ambiguity and security problems, which is why modern PHP code avoids $_REQUEST. You still need to understand it to read and maintain older code.


How $_REQUEST Is Built

The request_order Setting

The recommended php.ini files that ship with PHP (php.ini-development and php.ini-production) set:

request_order = "GP"

This means:

  1. Start with $_GET values.
  2. Add $_POST values; when a key exists in both, the POST value overwrites the GET value.
  3. Cookies are not included. If request_order is empty, PHP falls back to variables_order. Its built-in default ("EGPCS") includes cookies, so on servers without the recommended configuration, cookie values can end up in $_REQUEST and override GET and POST data.

Example: The Same Key in Two Sources

Consider a form submitted to a URL that also has a query parameter with the same name:

POST /update.php?id=10 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
id=25&status=shipped
<?php
echo "GET id: " . ($_GET['id'] ?? 'none') . "\n";
echo "POST id: " . ($_POST['id'] ?? 'none') . "\n";
echo "REQUEST id: " . ($_REQUEST['id'] ?? 'none') . "\n";
echo "REQUEST status: " . ($_REQUEST['status'] ?? 'none') . "\n";

Output (with request_order = "GP")

GET id: 10
POST id: 25
REQUEST id: 25
REQUEST status: shipped

$_REQUEST['id'] contains the POST value, because POST comes after GET in the order. Code reading $_REQUEST['id'] gets 25 without any indication that a different id was in the URL. If the server's configuration differs, the same code might get 10 — or a cookie value.


Why $_REQUEST Should Be Avoided

1. Ambiguity

The code no longer states where data comes from. A reader cannot tell whether $_REQUEST['email'] is expected from a form, a link, or a cookie, and the answer depends on server configuration.

Actions that change data — deleting, updating, paying — should only accept POST (or other non-GET methods) and must be protected with CSRF tokens. Code that reads $_REQUEST silently accepts the same parameters via GET as well:

<?php
// Legacy code: deletes a post using $_REQUEST
if (isset($_REQUEST['delete_id'])) {
    deletePost((int) $_REQUEST['delete_id']);
}

An attacker can now place a link or an image on another website:

<img src="https://example.com/admin/posts.php?delete_id=42" alt="">

When a logged-in administrator views that page, the browser requests the URL with the administrator's cookies, and the post is deleted. This is a Cross-Site Request Forgery (CSRF) attack. Reading only $_POST (combined with a CSRF token) prevents it, because a simple link or image cannot send a POST request. See CSRF Protection.

If cookies are included (when request_order is empty and variables_order contains C), a value stored in a cookie can override form data. Cookies can be set by other subdomains or by attackers in some scenarios, so they must never silently replace user input.

4. Harder Testing and Debugging

When a value is wrong, you must check three sources and the server configuration to find out where it came from.


Use the Specific Superglobal Instead

Data SourceUse
URL query string (links, search, filters, pagination)$_GET
Submitted forms (create, update, delete, login)$_POST
Cookies$_COOKIE
JSON request bodiesfile_get_contents('php://input')

Refactoring Legacy Code

<?php
// Before
$id = (int) ($_REQUEST['id'] ?? 0);
// After: this action changes data, so it accepts POST only
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
    http_response_code(405);
    header('Allow: POST');
    exit('Method not allowed');
}
$id = filter_var($_POST['id'] ?? null, FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
if ($id === false || $id === null) {
    http_response_code(400);
    exit('Invalid ID');
}

What Changed

  1. The request method is checked explicitly; other methods receive 405 Method Not Allowed with an Allow header naming the accepted method.
  2. The ID is read only from $_POST, so it cannot be supplied through a link.
  3. The ID is validated as a positive integer instead of being cast blindly — a cast would turn invalid input such as 'abc' into 0 silently. In a complete application, a CSRF token check would also be added before performing the action.

When Reading Several Sources Is Legitimate

Some endpoints genuinely accept the same parameter from either source — for example, a search page that works both from a link and from a form posted by an older client. Make that explicit instead of relying on $_REQUEST and server configuration:

<?php
function inputValue(string $key, string ...$sources): mixed
{
    $arrays = ['get' => $_GET, 'post' => $_POST];
    foreach ($sources as $source) {
        if (array_key_exists($key, $arrays[$source] ?? [])) {
            return $arrays[$source][$key];
        }
    }
    return null;
}
// Request: GET /search.php?q=php+loops
$query = inputValue('q', 'post', 'get');
echo "Search: " . htmlspecialchars((string) $query) . "\n";

Output

Search: php loops

The call inputValue('q', 'post', 'get') documents both the allowed sources and their priority, independent of php.ini. In frameworks, request objects provide similar methods, such as $request->input('q') in Laravel, which document exactly which sources they read.


Checking the Configuration

<?php
echo 'request_order: "' . ini_get('request_order') . '"' . "\n";
echo 'variables_order: "' . ini_get('variables_order') . '"' . "\n";
request_order: "GP"
variables_order: "GPCS"

If you maintain an application that relies on $_REQUEST, check these values on every server it runs on, because different configurations change the behavior.


Common Mistakes

Using $_REQUEST for Actions That Change Data

Effect: Actions can be triggered by links, enabling CSRF attacks. Fix: Accept only POST (or PUT/PATCH/DELETE in APIs) and verify CSRF tokens.

Assuming a Specific Override Order

Effect: Different servers produce different values. Fix: Read from $_GET or $_POST explicitly.

Expecting $_REQUEST to Contain Cookies (or Not)

Effect: Behavior changes between environments. Fix: Read cookies from $_COOKIE only.

Modifying $_GET and Expecting $_REQUEST to Change

Effect: $_REQUEST is built once at the start of the request; later changes to $_GET or $_POST are not reflected. Fix: Do not modify superglobals; work with validated copies.


Best Practices

  • Avoid $_REQUEST in new code; use $_GET, $_POST, and $_COOKIE explicitly.
  • Make state-changing endpoints POST-only and protect them with CSRF tokens.
  • When several sources are allowed, encode the priority in your own code.
  • When maintaining legacy code, check request_order and variables_order on each server. Official reference: https://www.php.net/manual/en/reserved.variables.request.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else User-defined Functions Slicing Strings Function Arguments PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting Error Logging HTTP Headers and Redirects Output Buffering Sending Email PHP cURL Consuming REST APIs PHP Generators AJAX PHP AJAX Database AJAX XML AJAX Live Search AJAX Poll AJAX with JSON Security Introduction Password Hashing SQL Injection Prevention XSS Prevention Garbage Collection Project: Simple Blog PHP What is OOP PHP Classes/Objects The $this Keyword Access Array Items Update Array Items Add Array Items Remove Array Items Sorting Arrays Multidimensional Arrays Array Destructuring Array Spread Operator Search in Arrays Merge Arrays PHP Abstract Classes PHP Interfaces Polymorphism PHP Traits PHP Static Methods PHP Static Properties Late Static Binding Magic Methods Object Cloning MySQL Database MySQL Connect MySQL Create DB MySQL Create Table MySQL Insert Data MySQL Get Last ID MySQL Insert Multiple MySQL Prepared MySQL Select Data MySQL Where Debugging PHP Project: Image Upload Gallery $_SESSION $_ENV PHP RegEx RegEx Patterns Heredoc and Nowdoc RegEx Modifiers preg_match preg_replace preg_split PHP RegEx Functions Nullable Types Mixed and Never Types Nullsafe Operator PHP Attributes PHP Fibers Readonly Classes Property Hooks (PHP 8.4) Asymmetric Visibility (PHP 8.4) Reflection API SPL Data Structures Composer PHP Form Handling PHP XML Parsers PDO Transactions PDO Error Handling PHP XML Parsers PHP SimpleXML Parser PHP SimpleXML - Get PHP XML Expat Parser PHP DOM Parser PHP XMLReader PHP XMLWriter AJAX Intro PHP Class Constants Encryption with Sodium Recursive Functions Variable Functions Anonymous Functions Closures Arrow Functions First-class Callable Syntax PHP Arrays Indexed Arrays Associative Arrays Create Arrays Variables Scope Static Variables Variable Variables PHP Echo / Print PHP printf / sprintf PHP Data Types PHP Booleans PHP NULL PHP Strings String Functions array_map / array_filter / array_reduce Array Functions What Are Superglobals? $GLOBALS What Is `$_SERVER` ? $_REQUEST $_POST $_GET $_FILES $_COOKIE
Ask about this post
AI Ask about this post

Ask questions about $_REQUEST and get answers drawn from it.

Signed-in readers only.