Skip to content
Theory · PHP and the web · lesson 2 of 7

$_GET, $_POST and forms

In a restaurant an order comes on a slip. The customer writes the dish, the quantity and any wishes on it. A slip may arrive half filled in, completely blank or filled in by a stranger's hand—the cook finds out only when reading it.

In PHP such slips are the request data. Let's see where they are kept and what to expect from them.

Parameters in the address: $_GET

An address can carry data. Everything after ? is the query parameters: "name=value" pairs separated by &. For the address /menu.php?page=3&city=, PHP puts the parameters into the array $_GET before the first line of your program runs.

$_GET is a superglobal: an array PHP fills in by itself, visible anywhere in the program, even inside a function.

In the terminal there is no request, so in the examples the first line stands in for one: it assigns $_GET itself. On the built-in server you remove this line, and PHP fills in the array.

PHP
<?php

$_GET = ['page' => '3', 'city' => ''];
var_dump($_GET['page'] ?? 1); // string(1) "3"
var_dump($_GET['sort'] ?? 'name'); // string(4) "name"
var_dump($_GET['city'] ?? 'Paris'); // string(0) ""

The first line matches the address ?page=3&city=. A parameter arrives in one of three forms, and ?? treats each of them differently.

The parameter is there

$_GET['page'] is the string '3', not a number. A parameter's value arrives as a string, even one made of digits only; only a name with [], as in tags[]=a, gives an array. ?? sees that the key exists and the value is not null, and returns '3'.

The parameter is missing

The address had no sort parameter, so $_GET has no such key. A plain read of $_GET['sort'] would give the warning Warning: Undefined array key "sort". As you already know, ?? checks the key first and quietly takes the value on its right—'name'.

The parameter is empty

The piece city= sends the key city with an empty string. A form field the visitor left blank arrives the same way. ?? reacts only to a missing key and null, so it keeps the empty string and does not substitute 'Paris'.

A string to a number: (int)

A page number is needed as a number, so the value is cast to int:

PHP
$_GET = ['page' => '3', 'size' => 'abc'];
$page = (int) ($_GET['page'] ?? 1);
$size = (int) ($_GET['size'] ?? 10);
var_dump($page); // int(3)
var_dump($size); // int(0)

Let's go through it step by step:

  1. The parentheses around $_GET['page'] ?? 1 make (int) apply to the result of ??.
  2. The string '3' turns into int(3).
  3. The visitor typed abc into size, and (int) quietly gives 0.

A cast turns a string into a number, but it does not check whether the number makes sense. Page 0 or size 0 is a mistake PHP will not report.

Forms and $_POST

A form is an order slip on the page itself. When the visitor presses the button of a form with method="post", the browser sends the field values not in the address but in the body of the request. PHP puts them into the superglobal $_POST under the names from the name attribute.

PHP
<?php

$_SERVER['REQUEST_METHOD'] = 'POST';
$_POST = ['dish' => 'Soup', 'qty' => '2'];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $dish = $_POST['dish'] ?? '';
    $qty = (int) ($_POST['qty'] ?? 1);
    echo $qty, ' x ', $dish, "\n"; // 2 x Soup
}
?>
<form method="post">
    <input name="dish">
    <input name="qty">
    <button>Order</button>
</form>

The two lines after <?php stand in for a submitted form; the rest is a real template:

  1. $_SERVER['REQUEST_METHOD'] holds the request method: 'GET' when the page was opened by its address, and 'POST' when such a form was submitted.
  2. If the form was submitted, the program reads the fields with ?? and casts the quantity to a number.
  3. Below ?> stands the form itself. It names no address, so the browser sends it to the same page.

The GET method suits reading: a page number, a search, a sort order. The POST method suits data that changes something: an order, a comment, a sign-up.

Interviewers often ask how GET differs from POST. GET parameters are visible in the address and stay in the browser history, while POST fields travel in the body of the request.

Both $_GET and $_POST are filled in by the visitor. They can erase a parameter, type ?page=abc or submit a form with fields the page does not have. In the restaurant picture this is a slip filled in by a stranger, and it cannot be trusted.

Only here the picture falls short: the cook sees who handed in the slip, while the program does not know who sent the request. A request can be sent without your form at all.

Common mistake

A parameter is read without ??:

PHP
<?php

$_GET = [];
$page = (int) $_GET['page']; // ✗
echo $page, "\n";
TEXT
Warning: Undefined array key "page"

The visitor opened the address without ?page=, and $_GET has no such key. PHP shows a warning and reads null, (int) null gives 0, and the program prints 0. The fix is a default value: $page = (int) ($_GET['page'] ?? 1);.

Key points

  • $_GET holds the parameters from the address, $_POST the fields of a submitted form, and a parameter without [] in its name arrives in them as a string.
  • A missing parameter is a missing key: $_GET['page'] ?? 1 gives the default without a warning.
  • An empty parameter city= is a key with an empty string, and ?? does not replace it.
  • (int) turns a string into a number, but 'abc' quietly becomes 0: a cast is not yet a check.