PHP$_GET & $_POST

$_GET & $_POST

$_GET and $_POST are the two superglobals you will use most often when a PHP page needs to react to input from a visitor. Both are associative arrays keyed by field name, but they draw their data from different parts of an HTTP request, and that difference is not just technical trivia — it should guide which one you reach for.

Where each one gets its data
  • $_GET reads name/value pairs from the URL query string, the part after ?, such as ?category=books&page=2.

  • $_POST reads name/value pairs from the body of the HTTP request, which is only present when the request method is POST.

  • A GET request has no body at all - everything the server sees arrives in the URL and headers.

  • A POST request keeps its data out of the URL, so it does not show up in browser history, bookmarks, or server access logs.

Reading a GET parameter

PHP
<?php
// Visiting /products.php?category=books&page=2
$category = $_GET['category'] ?? 'all';
$pageNum = (int) ($_GET['page'] ?? 1);

echo "Category: {$category}, page: {$pageNum}";
Category: books, page: 2
GET is for retrieval, POST is for mutation

HTTP defines GET as a "safe" and idempotent method: a GET request should only retrieve data and should be repeatable without side effects. That is why browsers freely re-fetch, cache, and prefetch GET URLs. POST carries no such guarantee — it is the method you use when the request changes something on the server, such as creating an account, submitting a comment, or placing an order. Following this convention matters beyond style: browsers, proxies, and search engine crawlers can and do re-issue GET requests automatically, so a "delete this item" link built on GET can be triggered accidentally.

A form that mutates data should use POST

HTML
<form method="post" action="/comments/create.php">
  <label for="body">Comment</label>
  <textarea id="body" name="body"></textarea>
  <button type="submit">Post comment</button>
</form>
Size and visibility limits

Query strings are limited in practice by the web server and browser, commonly somewhere around 2,000 to 8,000 characters depending on the stack, which makes $_GET unsuitable for large payloads such as file contents. $_POST bodies are governed instead by PHP's own post_max_size directive in php.ini, which defaults to a much more generous size and is the right place to look when a large form submission arrives empty.

Detecting a form that exceeded post_max_size

PHP
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && empty($_POST) && empty($_FILES)) {
    echo 'The submitted data was larger than this server allows.';
}
Always validate and escape

Regardless of which superglobal a value came from, it originated on the visitor's machine and must be treated as untrusted. Validate the shape and type you expect (an integer ID, a non-empty string, a valid email), and escape anything you echo back into HTML with htmlspecialchars() to prevent cross-site scripting.

Validating and escaping a POST field

PHP
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $name = trim($_POST['name'] ?? '');

    if ($name === '') {
        echo 'Name is required.';
    } else {
        $safeName = htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
        echo "Thanks, {$safeName}!";
    }
}
Never echo raw superglobal data
Printing `$_GET['name']` or `$_POST['name']` directly into an HTML response without `htmlspecialchars()` lets a visitor inject a `<script>` tag through that field and have it execute in every other visitor's browser. Escaping on output is not optional polish — treat it as a required step every time superglobal data reaches HTML.
Quick comparison

Aspect

$_GET

$_POST

Data location

URL query string

Request body

Visible in URL/history

Yes

No

Typical use

Search, filters, pagination

Login, forms that change data

Practical size limit

A few thousand characters

Governed by post_max_size

Cacheable/idempotent

Yes, by convention

No, by convention

Tip
When in doubt, ask "does this request change anything on the server?" If yes, use POST. If it only reads or filters existing data, GET keeps the URL shareable and bookmarkable, which is a real usability win.