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

It provides this via $input->get, $input->post, $input->cookie, $input->urlSegment(n) and $input->pageNum. While you could also use PHP's $_GET, $_POST, and $_COOKIE (superglobal) variables, $input provides these benefits:

  • You don't have to worry about PHP's magic_quotes, as values provided by $input are never escaped.
  • $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. 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 PHP's htmlentities() or htmlspecialchars() 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 htmlentities("$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.

$input->whitelist()

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 = substr(strip_tags($input->get->query), 0, 50);
$input->whitelist('query', $value);
// in some other file, echo the search text in the input box
$value = htmlentities($input->whitelist->query, ENT_QUOTES);
echo "<input type='text' name='query' value='$value' />";

Retrieving URL segments via $input->urlSegment(n)

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.

Note: you can also retrieve the first URL segment via $page->urlSegment. This method has been deprecated, but will continue to work for some time.

Retrieving page numbers via $input->pageNum

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:

/path/to/some-page/page4

…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

$input->pageNumReturns the current page 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's and do not count towards the limit of 3 URL segments.

Note: you can also retrieve the current page number via $page->pageNum. This method has been deprecated, but will continue to work for some time.

Comments

  • Alan Bristow

    Alan Bristow 6 years ago 42

    Correction:

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

    Should read:

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

    PS: Please check my correction cleverer-at-PW-than-me people ;)

  • MilenKo

    MilenKo 11 months ago 11

    Hello. I am trying to use urlSegments for my new profile and am stuck at $input->urlSegment1, 2, 3 not having a value.

    It is not yet clear to me which template I need to enable the urlSegments for, to make sure everything is working fine.

    Let's say I have a template called 'category' and another one 'category-list'. The URL I need to segment is: http://somedomain.com/category/test. The 'category' template is used to list all the categories with an image, description, link etc. The 'category-list' template is used to show the pages that have the category from the second segmennt assigned to it (in the example: 'test').

    So to make it work properly should I allow the urlSegment on 'category' , on 'category-list' or on both?

    Trying to print $input->urlSegment1 shows empty result (same for 2 & 3).

Post a Comment

Your e-mail is kept confidential and not included with your comment. Website is optional.