Menu

PHP $_GET and $_POST: Read Query Strings and Form Data

$_GET holds the query string of the URL (?page=2 gives $_GET['page']) and $_POST holds the fields of a form sent with method="post". Learn to read both safely, build links with http_build_query, check $_SERVER['REQUEST_METHOD'], and choose between GET and POST.

This page includes runnable editors - edit, run, and see output instantly.

$_GET is an array of the URL's query string, so article.php?id=42&lang=en gives $_GET['id'] === '42' and $_GET['lang'] === 'en'. $_POST is an array of the fields of a form sent with method="post". Read both with a default, $_GET['id'] ?? null, because the key is missing whenever the parameter is.

Run the block, then click the links: each click runs the script again with $_GET filled from the link's query string.

$_GET['lang'] is whatever the URL says, not only the three links you printed. Anyone can type ?lang=<script> into the address bar, which is why the block looks the value up in $languages instead of printing it, and escapes the one place it does print request data.

Read a number from the query string

Every value in $_GET is a string. For a page number, validate and convert in one step with filter_var() and fall back to a default when the value is missing, not a number, or out of range. Click through the pages, then try the Page 999 and Page abc links.

filter_var() returns the integer 3 for "3" and the default option for any other string, so $page is always a usable int. The filter_var page lists the other validators.

Read form data with $_POST

A form with method="post" sends its fields in the request body, and PHP puts them in $_POST under each input's name. $_SERVER['REQUEST_METHOD'] tells you whether the current request is the first visit (GET) or a submit (POST). Fill in the form and press Send to see both.

An empty text input is still sent, as "", so after a submit $_POST['title'] exists even if the visitor typed nothing. On a server REQUEST_METHOD is always set; the ?? 'GET' only keeps the script quiet when you run the file with php on the command line. The full pattern for validating and redisplaying a form is on the forms page.

A search form with method="get"

Use GET for a form whose result should be a shareable URL, like a search box. The browser turns the fields into a query string (?q=sort&level=beginner) and the script reads them from $_GET, exactly like a link. Search for array or string.

Writing "?q=$q&page=2" by hand breaks as soon as $q contains a space, & or #. http_build_query() encodes every value for you, and the result goes through htmlspecialchars() when it lands in an href, because & should be &amp; inside HTML.

parse_str() with two arguments is how PHP builds $_GET from a query string, so it is handy for testing. Always pass the second argument; the old one-argument form that created variables was removed in PHP 8.

$_REQUEST and why to avoid it

$_REQUEST is $_GET and $_POST merged into one array. The php.ini files PHP ships set request_order = "GP", so when both contain the same key, POST wins; without that setting, cookies are merged in too:

<?php
// POST /save.php?id=1 with a form field id=2
echo $_GET['id'];      // "1"
echo $_POST['id'];     // "2"
echo $_REQUEST['id'];  // "2"

It looks convenient, but it hides where a value came from. A handler that deletes a record on $_REQUEST['id'] can be triggered by a plain link, which is exactly what POST-only actions are meant to prevent. Read $_GET or $_POST by name instead.

GET vs POST: which one to use

GETPOST
Where the data travelsIn the URL: ?q=php&page=2In the request body
Read it with$_GET$_POST
Bookmark, share, back buttonYesNo (the browser asks to resend)
LengthLimited by the URL (a few thousand characters is safe)Limited by post_max_size (8M by default)
File uploadsNoYes, with enctype="multipart/form-data" (read $_FILES)
Use forSearch, filters, sorting, paginationLogin, sign up, saving, deleting, payments

The rule that matters: a GET request must not change anything. Browsers prefetch links, crawlers follow them, and people share them, so a ?delete=5 link will eventually be followed by something that was not meant to delete. Neither method is encrypted on its own: HTTPS protects both, and POST only keeps the data out of the URL, the browser history and server logs.

Frequently Asked Questions

How do I get a parameter from the URL in PHP?

Read it from $_GET with a default: for page.php?id=42, $id = $_GET['id'] ?? null; gives the string "42". Every value is a string (or an array for id[]=), so convert and validate it, for example with filter_var($id, FILTER_VALIDATE_INT).

What is the difference between $_GET and $_POST?

$_GET comes from the URL's query string, so it is visible, bookmarkable and limited in length; use it for searches, filters and pages. $_POST comes from the request body of a form sent with method="post"; use it for anything that changes data, like saving, buying or logging in.

How do I check if a GET parameter exists in PHP?

Use isset($_GET['q']), which is false when the key is missing or null. To also treat an empty value (?q=) as missing, compare the trimmed value: trim($_GET['q'] ?? '') !== ''.

Should I use $_REQUEST in PHP?

Usually not. $_REQUEST merges $_GET and $_POST (and, depending on request_order, cookies), so you cannot tell where a value came from, and a link can supply a value you expected from a form. Read $_GET or $_POST explicitly.

How do I check if a request is GET or POST in PHP?

Compare $_SERVER['REQUEST_METHOD']: if ($_SERVER['REQUEST_METHOD'] === 'POST') { ... }. This is more reliable than isset($_POST['submit']), which fails when the button has no name or when the form is sent by JavaScript or another script without that field.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED