$_GET

Yo Yogesh.M Updated 29 Oct 2026
7 min read

What Is $_GET?

In simple terms: $_GET is an array containing the parameters in the URL after the ? — the query string. For the address products.php?category=books&page=2, $_GET contains ['category' => 'books', 'page' => '2']. Technically: $_GET is a superglobal that PHP fills by parsing the query string of the requested URL, regardless of the request method. Parameters arrive from links, from forms submitted with method="get", and from any URL typed or generated by a client.

When GET Parameters Are the Right Choice

GET parameters describe what to show, not what to change:

Good UsesAvoid For
Search termsPasswords, tokens, personal data
Filters and sortingCreating, updating, or deleting data
PaginationLarge amounts of data
Selecting an item to view (?id=42)Anything that must not be repeated by reloading
Tracking the source of a visit (?ref=newsletter)

Because the parameters are part of the URL, the resulting page can be bookmarked, shared, and reloaded — which is exactly what users expect from search results and product listings. The same property makes GET unsuitable for sensitive data: URLs are stored in browser history, server logs, analytics tools, and Referer headers.


Reading Query Parameters

<?php
// Request: GET /products.php?category=books&page=2&sort=price_asc
$category = $_GET['category'] ?? 'all';
$page = $_GET['page'] ?? '1';
$sort = $_GET['sort'] ?? 'newest';
$search = $_GET['q'] ?? '';
var_dump($category, $page, $sort, $search);

Output

string(5) "books"
string(1) "2"
string(9) "price_asc"
string(0) ""

Key Points

  • Every value is a string — even page, which looks like a number. Validate and convert before using it as an integer.
  • Parameters that are not in the URL (q) are missing from $_GET; ?? provides a default without a warning.
  • Parameter names are case-sensitive: ?Page=2 does not set $_GET['page'].

How the Query String Is Parsed

PHP decodes the query string with the same rules as parse_str(), which lets you see the result directly:

<?php
$queryString = 'q=php+%26+mysql&tags[]=new&tags[]=sale&price[min]=100&price[max]=500&empty=&flag';
parse_str($queryString, $params);
var_dump($params);

Output

array(6) {
  ["q"]=>
  string(11) "php & mysql"
  ["tags"]=>
  array(2) {
    [0]=>
    string(3) "new"
    [1]=>
    string(4) "sale"
  }
  ["price"]=>
  array(2) {
    ["min"]=>
    string(3) "100"
    ["max"]=>
    string(3) "500"
  }
  ["empty"]=>
  string(0) ""
  ["flag"]=>
  string(0) ""
}

What This Shows

In the URLIn $_GET
+A space
%26& (URL-encoded characters are decoded)
tags[]=new&tags[]=saleA list: ['new', 'sale']
price[min]=100A nested array: ['min' => '100']
empty= and flag (no =)Empty strings

Validating GET Parameters

Since users can type any URL, every parameter needs validation.

Integers

<?php
// Request: GET /products.php?page=abc
$page = filter_var($_GET['page'] ?? 1, FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
if ($page === false) {
    $page = 1;
}
var_dump($page);

Output

int(1)

FILTER_VALIDATE_INT returns an int for valid input and false otherwise. min_range rejects zero and negative pages.

Allow-Lists for Fixed Choices

<?php
// Request: GET /products.php?sort=price;DROP
$allowedSorts = ['newest', 'price_asc', 'price_desc', 'rating'];
$sort = $_GET['sort'] ?? 'newest';
if (!in_array($sort, $allowedSorts, true)) {
    $sort = 'newest';
}
echo $sort . "\n";

Output

newest

Values such as sort orders often end up in SQL (ORDER BY), where placeholders cannot be used for column names. An allow-list is the safe way to handle them: only known values are ever used.

filter_input()

filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT) reads and validates in one step. It returns null if the parameter is missing and false if it is invalid. Note that it reads the original request data (changes to $_GET do not affect it) and returns null in command-line scripts, which can make testing harder. Validation is covered in detail in PHP Filters.


The "String or Array" Problem

The client controls the shape of every parameter. Adding [] to a name turns a string into an array:

/search.php?q=php        → $_GET['q'] is "php"
/search.php?q[]=php      → $_GET['q'] is ["php"]

Code that passes the value to a string function then fails:

<?php
// Request: GET /search.php?q[]=php
try {
    $term = trim($_GET['q'] ?? '');
} catch (TypeError $e) {
    echo get_class($e) . ": " . $e->getMessage() . "\n";
}

Output

TypeError: trim(): Argument #1 ($string) must be of type string, array given

An uncaught TypeError produces a server error (500) — easy for anyone to trigger. Check the type when reading parameters:

<?php
function queryString(string $key, string $default = ''): string
{
    $value = $_GET[$key] ?? $default;
    return is_string($value) ? trim($value) : $default;
}

Escaping GET Values in Output

Displaying a search term back to the user is a classic cross-site scripting (XSS) vulnerability:

<!-- Vulnerable -->
<p>Results for: <?= $_GET['q'] ?></p>

A link such as /search.php?q=<script>stealCookies()</script> would execute the script in the victim's browser. Always escape:

<p>Results for: <?= htmlspecialchars($_GET['q'] ?? '') ?></p>

The same applies when inserting values into HTML attributes, JavaScript, or URLs. See Escaping Output (htmlspecialchars) and XSS Prevention.


Building URLs With Query Parameters

Never build query strings by concatenating raw values — special characters such as &, =, #, and spaces break the URL. Use http_build_query():

<?php
$params = ['q' => 'php & mysql', 'category' => 'books', 'page' => 2];
echo '/search.php?' . http_build_query($params) . "\n";
echo '/search.php?q=' . urlencode('C# basics') . "\n";

Output

/search.php?q=php+%26+mysql&category=books&page=2
/search.php?q=C%23+basics
  • http_build_query() encodes keys and values and joins them with &.
  • urlencode() encodes a single value; without it, # would start a URL fragment and the rest of the search term would be lost.
  • When printing a URL into an HTML attribute, also escape it with htmlspecialchars(), because & must be written as & in HTML.

Practical Example: Product Listing With Filters and Pagination

<?php
function readFilters(array $query): array
{
    $allowedSorts = ['newest', 'price_asc', 'price_desc'];
    $sort = is_string($query['sort'] ?? null) && in_array($query['sort'], $allowedSorts, true)
        ? $query['sort']
        : 'newest';
    $category = is_string($query['category'] ?? null) && preg_match('/^[a-z-]{1,30}$/', $query['category'])
        ? $query['category']
        : null;
    $page = filter_var($query['page'] ?? 1, FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
    return ['category' => $category, 'sort' => $sort, 'page' => $page === false ? 1 : $page];
}
function listingUrl(array $filters, array $changes = []): string
{
    $params = array_filter(
        array_replace($filters, $changes),
        fn($value) => $value !== null && $value !== '' && $value !== 1
    );
    return '/products.php' . ($params === [] ? '' : '?' . http_build_query($params));
}
// Simulates: GET /products.php?category=books&sort=price_desc&page=2&utm=promo
$filters = readFilters(['category' => 'books', 'sort' => 'price_desc', 'page' => '2', 'utm' => 'promo']);
print_r($filters);
echo listingUrl($filters, ['page' => 3]) . "\n";
echo listingUrl($filters, ['sort' => 'newest', 'page' => 1]) . "\n";
echo listingUrl($filters, ['category' => null, 'page' => 1]) . "\n";
// In the real page: $filters = readFilters($_GET);

Output

Array
(
    [category] => books
    [sort] => price_desc
    [page] => 2
)
/products.php?category=books&sort=price_desc&page=3
/products.php?category=books&sort=newest
/products.php?sort=price_desc

Step-by-Step Explanation

  1. readFilters() receives the query array as a parameter ($_GET in real use), which makes it testable with any input.
    • sort must be in the allow-list.
    • category must be a short lowercase slug; anything else means "no category filter" (null).
    • page must be a positive integer.
    • Unknown parameters (such as utm) are ignored.
  2. listingUrl() builds links that keep the current filters while changing some of them:
    • array_replace() applies the changes.
    • array_filter() removes empty values and page=1, so URLs stay short and canonical.
    • http_build_query() encodes everything safely.
  3. The three links show typical uses: "next page", "change sorting and go back to page 1", and "remove the category filter". Changing a filter resets the page to 1, because page 3 of the old results may not exist in the new results. Keeping URLs canonical (no redundant parameters) also helps search engines treat equivalent pages as one.

Common Mistakes

Using GET for Actions That Change Data

Effect: Links, prefetching browsers, and search engine crawlers can trigger deletions or orders; CSRF attacks become trivial. Fix: Use POST for changes.

Putting Sensitive Data in URLs

Effect: Passwords or tokens leak through history, logs, and Referer headers. Fix: Send sensitive data in POST bodies or headers.

Treating Parameters as Numbers Without Validation

Effect: "2abc", "-5", or "99999999999" cause wrong results or errors. Fix: Validate with filter_var() and range options.

Assuming Parameters Are Strings

Effect: ?q[]=x triggers a TypeError and a 500 error. Fix: Check with is_string() before using string functions.

Printing Parameters Unescaped

Effect: Reflected XSS. Fix: htmlspecialchars() for HTML output.

Concatenating Raw Values Into URLs

Effect: Broken links and injected parameters. Fix: http_build_query() or rawurlencode()/urlencode().


Best Practices

  • Use GET for safe, repeatable requests: viewing, searching, filtering, and paginating.
  • Read parameters with defaults, check their types, and validate them against allow-lists or patterns.
  • Escape parameters whenever they are printed.
  • Build links with http_build_query(), preserving current filters where appropriate.
  • Pass the query array into functions instead of reading $_GET deep inside your code. Official reference: https://www.php.net/manual/en/reserved.variables.get.php

0 Comments

Reviewed before they appear

No comments yet.

Data Mining
Introduction to Data Mining Data Mining Implementation Process Data Mining Architecture Data Mining Techniques KDD: Knowledge Discovery in Databases History of Data Mining Data Mining Tools Data Mining vs Machine Learning Facebook Data Mining Social Media Data Mining Methods Clustering in Data Mining Text Data Mining Bagging vs Boosting Data Mining vs Data Warehousing Social Media Data Mining Data Mining: Bayesian Classifiers Data Mining: World Wide Web Different Types of Clustering Bitcoin Mining and Blockchain Data Mining Orange Data Mining Data Mining vs Big Data Decision Tree Induction Educational Data Mining Data Mining in Healthcare Apriori Algorithm Data Integration in Data Mining Difference Between Data Mining and Text Mining Discretization in Data Mining Redundancy and Correlation in Data Mining Classification of Data Mining Systems Classification Algorithms in Data Mining Data Generalization in Data Mining Classification and Prediction in Data Mining Regression in Data Mining What Is an Outlier in Data Mining Data Cleaning in Data Mining Data Processing in Data Mining Data Mining Task Primitives Web Content Mining, Web Structure Mining, and Web Usage Mini Binning in Data Mining KDD vs. Data Mining Noise in Data Mining BIRCH in Data Mining Stemming in Data Mining Feature Transformation in Data Mining Visual and Audio Data Mining Class Comparison Methods in Data Mining Data Selection in Data Mining Tasks and Functionalities of Data Mining Ubiquitous and Invisible Data Mining Importance of Data Mining Data Quality in Data Mining Mining Frequent Patterns in Data Mining Data Warehouse and OLAP Technology for Data Mining Need for Data Mining Pattern Evaluation Methods in Data Mining Logarithms and Exponents in Complexity Analysis Time Series Clustering What is the C4.5 Algorithm and How Does It Work? Expanding Contractions in Text Mining Cosine Similarity in Data Mining Lazy Learning in Data Mining Neural Networks in Data Mining Building a Text Normalizer Shallow Parsing Data Pipeline Orchestration Big Data vs Small Data Myths of Data Mining Data Reduction in Data Mining Data Mining Models Difference Between Data Mining and Data Science Difference Between Data Mining and Statistics Difference Between Data Mining and Web Mining Difference Between Data Mining and Data Analysis Difference Between Business Intelligence and Data Mining Difference Between Data Mining and Data Visualization Data Mining vs Data Analytics Types of Data Mining Difference Between Data Profiling and Data Mining Predictive Analytics vs Data Mining Difference Between Data Mining and OLAP Descriptive and Predictive Data Mining Difference Between Spatial and Temporal Data Mining Difference Between Classification and Clustering in Data Min Hierarchical Clustering in Data Mining Density-Based Clustering in Data Mining What Is Aggregation in Data Mining?
Ask about this post
AI Ask about this post

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

Signed-in readers only.