The $input API variable

The $input variable is your connection to GET, POST and COOKIE variables, URL segments, and page numbers.

While you could also use PHP's $_GET, $_POST, and $_COOKIE (superglobals) variables, using $input provides these benefits (for starters):

  • You don't have to consider PHP's magic_quotes setting, as values provided by $input are never escaped.

  • You can optionally get an already-sanitized version of the input variable.

  • $input returns NULL if you access a variable that doesn't exist (no need to use isset() like with PHP's superglobals).

  • $input->whitelist provides a place for you to store input variables you have sanitized and want to share with ProcessWire or plugin modules.

  • Variables can be accessed in either object, array, or function fashion, according to your preference and need.

Please note that the values returned by $input->get, $input->post, and $input->cookie are just as dangerous as those returned by $_GET, $_POST and $_COOKIE. They do not have any sanitization or validation done to them, unless you have accessed them through a sanitization function (described further in this document). You should never use the data without making sure that it's valid. If you echo any keys or values from $input, you always want to encode them with ProcessWire's $sanitizer->entities() or PHP's htmlentities(), at minimum. ProcessWire provides some built-in sanitization and validation functions which you can access with $sanitizer.

Accessing GET, POST and COOKIE variables

  • $input->get provides access to your GET variables
  • $input->post provides access to your POST variables
  • $input->cookie provides access to your COOKIE variables

Below are examples of using one type of input or another, however, the syntax of $input->get, $input->post and $input->cookie are interchangable in the examples below.

Get the value of a GET variable called 'name'. The following 3 retrieval methods provide the same result:

$value = $input->get->name;   // access as object property
$value = $input->get['name']; // access as array index
$value = $input->get('name'); // access as function 

We'll repeat the same example for a POST variable, just to reiterate that the syntax is the same between get, post and cookie:

$value = $input->post->name;   // access as object property
$value = $input->post['name']; // access as array index
$value = $input->post('name'); // access as function 

If you access a variable that is not provided, then it returns null:

if($input->post->hello === null) {
  echo "hello doesn't exist";
} else if(!$input->post->hello) {
  echo "hello exists, but is blank";

You may also iterate through $input->get, $input->post and $input->cookie:

foreach($input->get as $key => $value) {
  echo $sanitizer->entities("$key = $value") . "<br />";

And you can count $input->get, $input->post and $input->cookie:

echo "There are " . count($input->cookie) . " cookie variables";

Lastly, if you don't care where the variable came from (whether get, post or cookie), and the variable name adheres to PHP conventions, you can retrieve it as an object property directly from $input. This would be like using the $_REQUEST superglobal in PHP.

$value = $input->name; 

This is a convenience, but not a best practice. You should care about where your variable came from, and your code will be more secure, and more readable, if you stick to specifying $input->get, $input->post or $input->cookie.

Sanitizing input while retrieving it

When you access a property from $input->get, $input->post, or $input->cookie, you are accessing a non-sanitized value. You can optionally sanitize the value as you retrieve it by wrapping the property name with a $sanitizer method. For example:

$firstName = $input->get->text('first_name');
$email = $input->post->email('email_address'); 

For more details, see a list of all $sanitizer methods in the $sanitizer API reference page.


The $input variable also provides the $input->whitelist() function. It is a place to keep input values that you have already validated and sanitized. While that may not seem particularly useful in it's own right, the reason it exists is so that other plugin modules may use the input data with the assumption that it is clean. It's also a handy means of passing clean values between your own templates and include files.

An example is the MarkupPagerNav plugin module, which provides an easy way for you to have pagination. Lets say that you used it to paginate search engine results. There would be one or more GET vars that formed the basis for the search query. You communicate what those GET vars are to the pagination routines by populating them in $input->whitelist(). That way, when someone clicks a page number in the navigation, the URL generated by the paginator retains all the details of the search query, and does so in a manner that we know is secure. You can also provide these variables to the paginator on your own, but at the cost of more code... using $input->whitelist just makes life easier.

Whitelist Usage

$input->whitelist($key, $value)Set a whitelist value
$input->whitelist($key)Get a whitelist value

Whitelist Example

Here is one way you might use the whitelist.

// sanitize the search text and whitelist it
$value = $sanitizer->text($input->get('query'));
$input->whitelist('query', $value);
// in some other file, echo the search text in the input box
$value = $sanitizer->entities($input->whitelist('query'));
echo "<input type='text' name='query' value='$value' />";


If the page (template) you are viewing allows URL segments after the page's URL, you may retrieve them with the $input->urlSegment(n) function or the $input->urlSegment1, $input->urlSegment2, and $input->urlSegment3 variables (and more if needed*).

Given a page that exists at the URL /page/to/page/, a URL of /path/to/page/aaa/ will return a 404 Page Not Found error by default. But if you enable URL segments for the page's template, then it will instead render the page and populate $input->urlSegment1 with "aaa".

Up to $config->maxUrlSegments (default 3) URL segments are allowed, so /path/to/page/aaa/bbb/ would populate $input->urlSegment1 with "aaa" and $input->urlSegment2 with "bbb". Likewise, /path/to/page/aaa/bbb/ccc/ would populate $input->urlSegment3 with "ccc" (in addition to the other two).

$input->urlSegment usage

$input->urlSegment($n)Retrieve the $n'th URL segment (1–3*)
$input->urlSegment1Retrieve the first: /path/to/page/aaa/
$input->urlSegment2Retrieve the second: /path/to/page/aaa/bbb/
$input->urlSegment3Retrieve the third: /path/to/page/aaa/bbb/ccc/

*You can add more URL segments by editing /site/config.php and updating the $config->maxUrlSegments setting.

Your URL segments setting is configured with your template in Setup > Templates > [some template] > URLs > URL Segments.

URL segments are compatible with caching. If caching is enabled for your template, ProcessWire will cache URL segment variations of a given request.


If you want to retrieve all URL segments at once, you can use $input->urlSegmentStr, which will return all the URL segments in a slash-separated string. So if the URL accessed was /path/to/page/a/b/c/ then the urlSegmentStr would contain "a/b/c".


If the page (template) you are viewing allows page numbers, you may retrieve the current page number from $input->pageNum. It corresponds to a /page[n] URL segment at the end of your URL. For example:


…would populate the value 4 in the $input->pageNum variable. By default, the pageNum value is always 1 unless it has been specifically set in the URL. The maximum page number value is 999.

$input->pageNum usage

Accessing $input->pageNum returns the current page (aka pagination) number from the URL (1–999).

In addition to providing a value that you can retrieve, ProcessWire uses the pageNum value internally in some cases. For any API functions that retrieve multiple pages and allow you to specify selectors (like $pages->find() and $page->children()), if you have specified a "limit=[n]" part in your selector, ProcessWire will assume pagination and use the $input->pageNum value to determine where to start the selection. If you want to disable this behavior for some reason, add a "start=[n]" (like "start=0") part to your selector in addition to your "limit=[n]".

Page numbers are compatible with template caching (up to 999 pages). Page numbers are also compatible with URL segments, but the page number must always be the last URL segment. Page numbers do not appear in your $input->urlSegment[n] values and do not count towards the limit of 3 URL segments.

$input API reference

This page just covers the basics. For full details on all the available methods and properties on $input, please see the full $input API reference.

Twitter updates

  • This post covers a few of the bigger updates in ProcessWire 3.0.154+3.0.155. This includes new live replacement of text in core and modules, a new method for creating canonical URLs, and some major upgrades to our input->urlSegment() method! More
    24 April 2020
  • A brief look at what's new in ProcessWire 3.0.154 in this forum post: More
    17 April 2020
  • This week we’ve got a few new and interesting core updates in progress, though none quite ready to release just yet. So rather than releasing version 3.0.154 today, I thought we'd instead take a brief look at what’s coming over the next few weeks… More
    3 April 2020

Latest news

  • ProcessWire Weekly #310
    The 310th issue of ProcessWire Weekly is going to be short and sweet: in this issue we'll walk you through the latest core updates, introduce a third party module called Twack, and check out a really gorgeous new site of the week. Read on! / 18 April 2020
  • ProcessWire updates and additions in progress
    This week we’ve got a few new and interesting core updates in progress, though none quite ready to release just yet. So rather than releasing version 3.0.154 today, I thought we'd instead take a brief look at what’s coming over the next few weeks. This post covers all the details.
    Blog / 3 April 2020
  • Subscribe to weekly ProcessWire news

“We chose ProcessWire because of its excellent architecture, modular extensibility and the internal API. The CMS offers the necessary flexibility and performance for such a complex website like ProcessWire offers options that are only available for larger systems, such as Drupal, and allows a much slimmer development process.” —xport communication GmbH