FastSitePHP\Web\Request

The Request Class represents an HTTP request and can be used to read content submitted by the browser or client.

Source Code

GitHub

رمز المثال

HTTP Request Object - Reading Query Strings, Form Fields, and Cookies

// The request object can be used obtain info from the client for an
// HTTP request. This includes query strings, form fields, cookies,
// headers, and more. The request object also contains functions to
// sanitize (“clean”) and safely read client info.

// Without using a Framework, Query Strings, Form Variables and other
// User Input can be read through PHP Superglobals [$_GET, $_POST, etc].
// Example, read the Query String Field [number]:
$number = $_GET['number'];

// If the query string [type] does not exist then the above code
// would throw an exception so to safely get the value you can first
// check if it is set.
$number = (isset($_GET['number']) ? $_GET['number'] : null);

// An additional line of PHP code can be used to force a numeric value:
$number = (int)$number;

// The Request object can be used instead to safely read the values, convert
// data types, etc. To use the Request object simply create one:
$req = new \FastSitePHP\Web\Request();

// You can then read query strings by name without including safety logic:
$number = $req->queryString('number');

// An optional 2nd parameter can be used to convert to a specific data type.
// In this example the value will be converted to an interger if it is valid
// otherwise null will be returned.
$number = $req->queryString('number', 'int?');

// In addition to [queryString()] functions [form()] and [cookie()] can be
// used in the same manner.
$value  = $req->form('field');
$cookie = $req->cookie('name');

// The Request object also contains a helper function to handle user input
// or objects where a value may or may not exist. This can be used to prevent
// errors when reading complex JSON object and to to sanitize (“clean”) data
// from any object or array.
//
// Function Definititon:
//     value($data, $key, $format = 'value?', $max_length = null)
//
// Data Example:
//     $_POST['input1'] = 'test';
//     $_POST['input2'] = '123.456';
//     $_POST['checkbox1'] = 'on';
//     $json = [
//         'app' => 'FastSitePHP',
//         'strProp' => 'abc',
//         'numProp' => '123',
//         'items' => [ ['name' => 'item1'], ['name' => 'item2'] ],'
//    ];
//
// Function Examples:
//    'test'        = $req->value($_POST, 'input1');
//    // Truncate the string to 2 characters:
//    'te'          = $req->value($_POST, 'input1',    'string', 2);
//    123.456       = $req->value($_POST, 'input2',    'float');
//    ''            = $req->value($_POST, 'missing',   'string'); // Missing
//    1             = $req->value($_POST, 'checkbox1', 'checkbox');
//    0             = $req->value($_POST, 'checkbox2', 'checkbox'); // Missing
//    true          = $req->value($_POST, 'checkbox1', 'bool');
//    'FastSitePHP' = $req->value($json,  'app');
//    'abc'         = $req->value($json,  'strProp',   'string?');
//    0             = $req->value($json,  'strProp',   'int');  // Invalid Int
//    null          = $req->value($json,  'strProp',   'int?'); // Invalid Int
//    123           = $req->value($json,  'numProp',   'int');
//    'item1'       = $req->value($json,  ['items', 0, 'name']);
//    'item2'       = $req->value($json,  ['items', 1, 'name']);
//    null          = $req->value($json,  ['items', 2, 'name']); // Missing
//
// See full documentation for more. If you need full validation rather than
// data cleaning see the [\FastSitePHP\Data\Validator] class.

HTTP Request Object - Request JSON and Content

// Create the Request Object
$req = new \FastSitePHP\Web\Request();

// Get the Request Content Type. This is a helper field that returns
// a simple value based on the 'Content-Type' header:
//     'json'      = 'application/json'
//     'form'      = 'application/x-www-form-urlencoded'
//     'xml'       = 'text/xml' or 'application/xml'
//     'text'      = 'text/plain'
//     'form-data' = 'multipart/form-data'
// If different the raw header value will be returned and if the header
// is not defined then [null] will be returned.
$type = $req->contentType();

// The Request body/content can be read from [content()]. If the Request Type
// is JSON then the object will be parsed and an object/array will be returned.
// If [contentType() === 'form'] then an array will be returned otherwise the
// body/content is returned as a string. In PHP a string can also be used for
// binary data as a string is simply array of bytes.
$body = $req->content();

// The [value()] function can be used to safely read nested values from a
// submitted JSON object. See other examples and docs for more on using the
// [value() function.
$value = $req->value($body,  ['items', 0, 'name']);

HTTP Request Object - Header Fields

// Create the Request Object
$req = new \FastSitePHP\Web\Request();

// Reading Common Header Fields can be done through functions:
$origin = $req->origin();
$userAgent = $req->userAgent();
$referrer = $req->referrer();
$client_ip = $req->clientIp();
$protocol = $req->protocol();
$host = $req->host();
$port = $req->port();

// When using functions with 'Accept' Headers an array of data is returned,
// and an optional parameter can be passed to return [true] or [false].
$accept_encoding = $req->acceptEncoding();
$accept_language = $req->acceptLanguage();

// Example:
//    'Accept-Language' Header Value = 'ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4'
// Returns:
//    [
//        ['value' => 'ru-RU', 'quality' => null],
//        ['value' => 'ru',    'quality' => 0.8],
//        ['value' => 'en-US', 'quality' => 0.6],
//        ['value' => 'en',    'quality' => 0.4],
//    ];

$accept_en = $req->acceptLanguage('en'); // true
$accept_de = $req->acceptLanguage('de'); // false

// Any header can be read when using the [header()] function:
$content_type = $req->header('Content-Type');
$user_agent = $req->header('User-Agent');

// Header Keys are Case-insensitive so the following all return the same value:
$content_type = $req->header('content-type');
$content_type = $req->header('CONTENT-TYPE');
$content_type = $req->header('Content-Type');

// All headers can be read from the [headers()] function:
$headers = $req->headers();

HTTP Request Object - Proxy Header Fields

// Create the Request Object
$req = new \FastSitePHP\Web\Request();

// Request Proxy Headers are used for key fields such as client IP when a
// web server sits behind a “proxy” server on a local network, for example
// a load balancer. Reading the values correctly is important for security,
// however in general with any programming language or framework reading proxy
// headers if often difficult and requires extra config. FastSitePHP makes
// the task easy with no config required.

// For example, simply reading the Client IP of the request can be done
// by reading the value of REMOTE_ADDR.
$client_ip = $_SERVER['REMOTE_ADDR'];

// If the load balancer is configured to provide the Client IP it will
// usually be one of the following Request Headers [X-Forwarded-For,
// Client-Ip, or Forwarded]. However since the end user can send data with
// the Request Header it must be read correctly. The standardized header
// [Forwarded] has a format like this:
//     'for=192.0.2.43, for="[2001:db8:cafe::17]";proto=http;by=203.0.113.43'
// While non-standard but widely used headers such as [X-Forwarded-For] use
// this format:
//     'client-ip1, client-ip2, proxy1, proxy2'
// FastSitePHP handles both formats.

// For example assume the load balancer is at '10.0.0.1', '10.0.0.2' is used
// for additional content filtering, and [X-Forwarded-For] came in with the
// the following value:
//     [REMOTE_ADDR]      =   '10.0.0.1'
//     [X-Forwarded-For]  =   "' OR '1'='1 --, 127.0.0.1, 54.231.1.5, 10.0.0.2"
// In this example, the following was submitted:
//     - Client - A SQL Injection String of "' OR '1'='1 --"
//     - Client - A localhost IP [127.0.0.1]
//     - Client - Actual IP [54.231.1.5]
//     - Server - 10.0.0.2

// When simply reading Client IP without any parameters the IP of the load
// balancer is returned for this example which is '10.0.0.1'.
$client_ip = $req->clientIp();

// Then when using the default 'from proxy' setting the correct User IP
// value of '54.231.1.5' is returned. If no proxy server is used then the
// default settings of 'from proxy' are safe to call.
$user_ip = $req->clientIp('from proxy');

// When using proxies an optional 2nd parameter of [$trusted_proxies] is
// avaiable. This defaults to the string 'trust local', however an array
// of specific IP or IP Ranges (CIDR format) can be used for more specific
// filtering. Additionally the first parameter [$option] can also be
// modified to read from different Request Headers.
$user_ip = $req->clientIp('from proxy', 'trust local');

// In addition to Client IP, proxy values can also be read for
// [Protocol, Host, and Port]:
$portocal = $req->protocol('from proxy'); // 'http' or 'https'
$host = $req->host('from proxy');
$port = $req->port('from proxy');

Request Object - Server Info

// The Request Object can return the Server IP and has a helper function
// [isLocal()] that returns true only if both the requesting client and
// the web server are on localhost ['127.0.0.1' or '::1']. In certain apps
// you may want to enable certain features for development or local work
// and these functions help with that.
$req = new \FastSitePHP\Web\Request();
$server_ip = $req->serverIp();
$is_local  = $req->isLocal();

// NOTE - the Web Server IP is often different than the actual Network IP.
// To obtain the network IP (location of the server) use the Networking
// Config Object instead:
$config = new \FastSitePHP\Net\Config();
$net_ip = $config->networkIp();

Methods

queryString($name, $format = 'value?')

Return a Request QueryString Value using format options from the [value()] function. Returns Null if the QueryString doesn't exist.

With native PHP Code Query String values can also be read from the [$_GET] Superglobal array. Example:

    $value = (isset($_GET['name']) ? $_GET['name'] : null)

Returns: mixed

form($name, $format = 'value?')

Return a Request Form Field Value using format options from the [value()] function. Returns Null if the Form Field doesn't exist.

With native PHP Form Field values can also be read from the [$_POST] Superglobal array. Example:

    $value = (isset($_POST['name']) ? $_POST['name'] : null)

Returns: mixed

Return a Request Cookie Value using format options from the [value()] function. Returns Null if the Cookie doesn't exist.

With native PHP Code Cookie values can also be read from the [$_COOKIE] Superglobal array. Example:

    $value = (isset($_COOKIE['name']) ? $_COOKIE['name'] : null)

Returns: mixed

verifiedCookie($name)

Use to read secure cookies that were created from [Response->signedCookie()]. Returns null if cookie is not set or if it cannot be verified.

Using this function requires the Application Config Value 'SIGNING_KEY'.

Returns: mixed

jwtCookie($name)

Use to read secure cookies that were created from [Response->jwtCookie()]. Returns null if cookie is not set or if it cannot be verified.

Using this function requires the Application Config Value 'JWT_KEY'.

Returns: mixed

decryptedCookie($name)

Use to read secure and secret cookies that were created from [Response->encryptedCookie()]. Returns null if cookie is not set or if it cannot be decrypted.

Using this function requires the Application Config Value 'ENCRYPTION_KEY'.

Returns: mixed

value($data, $key, $format = 'value?', $max_length = null)

Helper function to handle user input or objects where a value may or may not exist. This function is very flexible and depending upon the parameters checks if an array key, object property, or an array of keys/properties exists and returns the value in the desired format. This function is ideal for handling user input from PHP superglobals ($_GET, $_POST, $_COOKIE, $_SESSION) and data from JSON Objects.

This function can be used to sanitize (clean) data and return it in a needed format (example zero [0] for an integer instead of an invalid string or error message).

Options for the return format are specified in the parameter [$format]. Options that end with a question mark '?' will return either null or the value while options that do not end with a question mark are always converted to the specific data type:

    'value?'
    Optional value, returns the value as-is or null if not set

    'string'
    Always return a string type and an empty string if no data.
    Whitespace is trimmed (spaces, tabs, new lines, etc).

    'string?'
    Return string data type or null if not set or
    the string is empty. Whitespace is trimmed.

    'string with whitespace'
    Always return a string and keep any whitespace

    'int'
    Always return an int data type, if the value was
    not set or a valid integer then it will return zero.

    'int?'
    Return int or null

    'float'
    Always return an float/double data type, if the value
    was not set or a valid float then it will return zero.

    'float?'
    Return float or null

    'bool'
    Return a boolean (true or false).
    returns true if the value is '1', 'true', 'on', or 'yes'
    and false for all other values.

    'bool?'
    Return a boolean (true|false) or null
    Using strict bool validation values so the following rules apply:
    returns true if the value is '1', 'true', 'on', or 'yes'
    returns false if the value is '0', 'false', 'off', or 'no'
    returns null for all other values

    'checkbox'
    Check the value of an HTML Submitted Form Field Checkbox
    and convert it to a database bit value of 1 or 0. HTML
    Posted Forms if checked will have the value set to 'on'
    otherwise the field name will not be included in the POST.
    Specifying $format of 'bool' for a checkbox field will
    allow return true/false if that is desired over 1/0.

    'email?'
    Return a valid email address or null

    'url?'
    Return a valid url address beginning with 'http://' or 'https://' or null

Examples:
    $_POST['input1'] = 'test';
    $_POST['input2'] = '123.456';
    $_POST['checkbox1'] = 'on';
    $json = json_decode('{"app":"FastSitePHP","strProp":"abc","numProp":"123","items":[{"name":"item1"},{"name":"item2"}]}');

    'test'        = $req->value($_POST, 'input1');
    'te'          = $req->value($_POST, 'input1', 'string', 2); // Truncate string to 2 characters
    123.456       = $req->value($_POST, 'input2', 'float');
    ''            = $req->value($_POST, 'missing', 'string'); // Missing Item
    1             = $req->value($_POST, 'checkbox1', 'checkbox');
    0             = $req->value($_POST, 'checkbox2', 'checkbox'); // Missing Item
    true          = $req->value($_POST, 'checkbox1', 'bool');
    'FastSitePHP' = $req->value($json, 'app');
    'abc'         = $req->value($json, 'strProp', 'string?');
    0             = $req->value($json, 'strProp', 'int'); // Invalid Int
    null          = $req->value($json, 'strProp', 'int?'); // Invalid Int
    123           = $req->value($json, 'numProp', 'int');
    'item1'       = $req->value($json, array('items', 0, 'name'));
    'item2'       = $req->value($json, array('items', 1, 'name'));
    null          = $req->value($json, array('items', 2, 'name')); // Missing Item

Returns: mixed

header($name)

Return the value of a Header Field sent with the HTTP Request. If the key does not exist for then this function will return null. Header values are read directly from the PHP Superglobal $_SERVER Array.

Examples:
    $content_type = $req->header('Content-Type')
    $user_agent = $req->header('User-Agent')

    Header Keys are Case-insensitive so the following all return the same value
    $value = $req->header('content-type')
    $value = $req->header('CONTENT-TYPE')
    $value = $req->header('Content-Type')

Returns: string | null

headers()

Return an array of all HTTP Request Headers Fields. Header names will be capitalized so the following names ['Content-type', 'Content-Type', and 'CONTENT-TYPE'] would all be returned by this function as 'Content-Type' for the key in the array.

Returns: array

method()

Return the Request Method as a string ['GET', 'POST', 'PUT', etc].

Returns: string | null

contentType()

Read the specified request header 'Content-Type' and return a text string with a simple value 'json|form|text|xml|form-data' to indicate the type of request content, if unknown then the actual value, or if not set then null. This function can be used to show the return format of the input() function. The difference between 'form' and 'form-data' is 'form' is used to indicate a simple html form posted as 'application/x-www-form-urlencoded' while 'form-data' is for forms with possible files posted as 'multipart/form-data'. If the return type is 'form-data' then the input must be read using superglobal variables $_POST and $_FILES because content() and contentText() use 'php://input' which does not read from multipart forms.

Returns: string | null

content()

Read the request input stream and return the result as as an object, array, text, or null based on the specified content-type. This function is a different from contentText() which always returns the request input as a text string. This would commonly be used to handle posted JSON data or put form values to a web service. The supported return type formats are:
    *) 'json' which returns an associative array if text is parsed or
       null if invalid json
    *) 'form' which returns an associative array of the
       parsed form values
    *) All other input types are returned as text and it's
       up to the app developer to handle them. XML is not handled
       by default because there are multiple XML Libraries built
       into PHP and it would be up to the app developer to determine
       the best one to use plus XML is now becoming a lot less
       common and typically being replaced with JSON services.

Returns: mixed

contentText()

Read the request input stream and return the result as text. This reads 'php://input' which can only be read once prior to PHP 5.6; this function saves the result and can be read over and over. The return value is always a string regardless of type. This would commonly be used to handle posted JSON data or put form values to a web service. To return request input in the actual format sent from the client use the function input().

Returns: string

bearerToken()

Return a Bearer Token value from the Authorization Request Header. If the header is not set or the token is invalid then null will be returned.

Bearer Tokens are commonly used with API’s and Web Services. Token values are defined by the app and can include OAuth 2.0, JSON Web Tokens (JWT), or custom formats.

Example Request:
    'Authorization: Bearer abc123'

This function returns:
    'abc123'

The web standard (RFC 6750) is focused around OAuth 2.0 however it defines a flexible format for the token value to support various encoded token types:
    Bearer {OAuth 2.0}
    Bearer {JWT}
    Bearer {Hex}
    Bearer {Base64}
    Bearer {Base64url}

Returns: string | null

isXhr()

Return true if the request was submitted with the header [X-Requested-With] containing the value [XMLHttpRequest]. This header is sent with jQuery and other popular JavaScript Frameworks when making web service calls.

An example of using this function for on a site would be if a Web Form allows for both Form POST's and Web Service Calls to the same URL. For this example the server code could check if the function was submitted as an xhr request and if so return JSON otherwise return HTML.

Returns: bool

origin()

Get the value of the 'Origin' Request Header if set or null if not set. This header value is submitted by Web Browsers for Cross-Origin Resource Sharing (CORS) Requests. This function can be used with the cors() function to handle CORS Requests. In JavaScript the origin of a web site can be determined from the property [window.location.origin]. For reference links related to the 'Origin' Header refer to the cors() function.

If a page is being viewed directly from the file system [window.location.origin] will show 'file://' and submit a string value of 'null' to the server. The string value of null is handled and returned as null with this function.

Returns: null

userAgent()

Get the value of the 'User-Agent' Request Header or null if not submitted. The 'User-Agent' header is a string that often provides info related to what Browser or HTTP client the user is using and what OS they are on. The header value is commonly spoofed meaning requests will say they are a specific browser and OS when they are in fact something else so user agent values generally cannot be relied upon. However if a site is tracking User Agent strings then it can provide a general overview of who is using the site and what devices or browsers they are using. In JavaScript the User Agent can be determined from the property [navigator.userAgent].

Returns: null

referrer()

Get the value of the 'Referer' Request Header. The Referer Header provides address of a web page or web site that linked to the current request. This value will also be set by search engines (e.g.: Google or Bing) when a user is coming from the search engine. The Referer header is a defined web standard and was originally defined as a misspelled English word so it has been kept as a misspelled word for technical purposes; just like JavaScript this function uses the correctly English Spelling. In JavaScript from a Web Browser this value can be determined from the property [document.referrer].

Returns: null

clientIp($option = null, $trusted_proxies = 'trust local')

Return the IP Address of the remote client (the end-user) that is requesting the webpage or resource. For security if no options are specified this function will return the server variable REMOTE_ADDR. However depending upon the environment, the server variable REMOTE_ADDR might not the IP Address of the remote client but rather the IP Address of the a Proxy Server such as a Load Balancer. For websites that use a proxy server this function provides a number of options to securely read the IP Address of the client. If you do not use a proxy server then call this function without passing any arguments if you need the client's IP address.

Reading the remote client IP Address is a possible source of attacks by malicious clients for insecure web frameworks and code. FastSitePHP is designed for security out of the box so using this function with default parameters is secure however if using a proxy server the actual web server and environment must also be properly configured. For an example of this type of attack see comments in the function [isLocal()].

The server variable REMOTE_ADDR on most server environments will always contain the IP Address of the connecting client. Generally this value is always safe to read. If a proxy server is used and configured to provide the client's IP Address then it will likely be sent in a Request Header such as 'X-Forwarded-For', 'Client-IP', or 'Forwarded'. These request headers typically use the following format:

   X-Forwarded-For: Client1, Client2, Proxy1, Proxy2
   (Example): 127.0.0.1, 54.231.1.14, 10.0.0.1, 10.0.0.2

In this example only the value Client2 would be safe to read as it is the last "untrusted" IP Address to reach a "trusted" proxy server. The IP Address specified in Client1 could be anything (for example 127.0.0.1 to spoof localhost or a SQL Injection Attack) which is why only the value from Client2 would be valid for IP Reporting or Logging. The terms "untrusted" and "trusted" are commonly used when referring to proxy servers and they mean that an "untrusted" client is one that exists on the public internet while a "trusted" client is a known computer (usually on a private network) that you have control over or trust as providing valid IP info.

This function has two parameters [$options] and [$trusted_proxies]:

    $options (string or null):
        *) Defaults to null which returns REMOTE_ADDR and results in remote
           IP Addresses not being checked.
        *) 'from proxy' - If specified this will check the following three server variables
           [ 'HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_FORWARDED' ] which maps to
           Request Headers [ 'X-Forwarded-For', 'Client-IP', 'Forwarded' ]. Each of the
           Headers is checked and the matching header is used to lookup the IP Address.
           If multiple headers exist with different IP Addresses then an exception
           is raised with this option because it would not be possible for the application
           to know which header is correct. The three headers checked are the most
           common headers used for specifying the client's IP Address. Headers
           'X-Forwarded-For' and 'Client-IP' are non-standard headers but widely used.
           The header 'Forwarded' is part of Web Standard RFC 7239 however it is relatively
           new (defined in 2014) and not yet widely used.
        *) 'HTTP_X_FORWARDED_FOR' or the key of a Server Variable for the Request Header
           that contains the Client's IP Address from the Proxy Server. For example if
           the client's IP Address is sent in the request header 'X-Forwarded-For' then
           the server variable 'HTTP_X_FORWARDED_FOR' will contain the value of the header.
           Even though FastSitePHP allows for the simple option 'from proxy', entering the
           actual server variable is good practice because it allows the application to
           ignore all other headers. In some cases a valid public client can also be behind
           a proxy server that uses one of the headers which is different than the header
           used by the web server. In this case if the headers are not correctly modified
           by the proxy server then this function will raise an exception because
           it doesn't know which header value to use.

    $trusted_proxies (string or array):
        *) This option only applies if the parameter [$option] is not null.
        *) 'trust local' - The default value. This uses CIDR Notation string
           values returned from the array [$app->privateNetworkAddresses()]
           and also allows for Web Standard RFC 7239 Obfuscated and
           Unknown Identifiers.
        *) Optionally this parameter can be set with a string or an array of
           specific IP Addresses or CIDR Notation IP Ranges to trust.
        *) If using a proxy server then the default value 'trust local' should
           be used for most websites as it is secure and only allows for
           IP Addresses that would appear on a private network to be trusted.

Examples:
    Remote Address and one 'X-Forwarded-For' header on a private network
        REMOTE_ADDR = '10.1.1.1'
        HTTP_X_FORWARDED_FOR = '54.231.1.4, 10.1.1.2'

        '10.1.1.1' = req->clientIp()
        Function called without any parameters so the value from REMOTE_ADDR is returned

        '54.231.1.4' = req->clientIp('from proxy')
        '54.231.1.4' = req->clientIp('from proxy', 'trust local')
        '54.231.1.4' = req->clientIp('from proxy', $app->privateNetworkAddresses())
        Client IP Address is returned when using 'from proxy' as the function
        determines the proxy addresses. 'trust local' is the default option and
        it uses an array of CIDR Notation String Values from the function
        [$app->privateNetworkAddresses()].

        '10.1.1.2' = req->clientIp('from proxy', '10.1.1.1')
        Only the IP Address '10.1.1.1' is trusted so '10.1.1.2' is returned

        '54.231.1.4' = req->clientIp('HTTP_X_FORWARDED_FOR')
        Client IP Address is returned when using the specific server variable as an option

    Three Client IP Addresses specified ("' OR '1'='1' --", 127.0.0.1, 54.231.1.5).
    The left-most address is an attempted SQL Injection String while the 2nd address
    '127.0.0.1' is an attempt to spoof localhost permissions. Only the 3rd Address
    '54.231.1.5' is the IP Address that the client actually connected from.
        REMOTE_ADDR = '10.0.0.1'
        HTTP_X_FORWARDED_FOR = "' OR '1'='1 --, 127.0.0.1, 54.231.1.5"

        '10.0.0.1' = req->clientIp()
        Function called without any parameters so the value from REMOTE_ADDR is returned

        '54.231.1.5' = req->clientIp('from proxy')
        The correct Client IP Address is returned and the two left-most values are ignored

    The Client Connects from their own proxy '54.231.1.7' and specified the final Client IP
    '54.231.1.6' in two Request Headers 'X-Forwarded-For' and 'Client-Ip'. An internal
    Proxy Server is configured to only handle 'X-Forwarded-For'.
        REMOTE_ADDR = '10.0.0.2'
        HTTP_X_FORWARDED_FOR = '54.231.1.6, 54.231.1.7'
        HTTP_CLIENT_IP = '54.231.1.6'

        req->clientIp('from proxy')
        An Exception is thrown because the IP Request Headers are
        incompatible and the client cannot be determined.

        '54.231.1.7' = req->clientIp('HTTP_X_FORWARDED_FOR')
        The correct Client IP is returned because the correct server variable is specified.

    Client IP supports both IPv4 and IPv6. In this example an IPv6 Unique local address
    ('fc00::/7') is specified as the trusted proxy. In CIDR Notation the address 'fc00::/7'
    also covers the IP Range 'fd00::/8' which is why REMOTE_ADDR starts with 'fddb:'.
        REMOTE_ADDR = 'fddb:1273:5643::1234'
        HTTP_X_FORWARDED_FOR = '2001:4860:4801:1318:0:6006:1300:b075'

        '2001:4860:4801:1318:0:6006:1300:b075' = req->clientIp('from proxy')
        The correct public IPv6 Address (in this case a Googlebot) is returned

Returns: string | null

protocol($option = null, $trusted_proxies = 'trust local')

Return the protocol (a string value of either 'http' or 'https') that was used to make the request. If the web server is behind a proxy server (for example a load balancer) then optional parameters allow for the protocol to be safely read from a proxy request header. If not using a proxy server then functions rootDir() and rootUrl() can be used to easily obtain needed URLs for the hosted site instead of using this function.

For reading proxy headers functions clientIp(), protocol(), host(), and port() all share similar parameters; refer to clientIp() documentation for detailed comments on the options. For protocol() if the [option] parameter is set to 'from proxy' then the value is read from the request header 'X-Forwarded-Proto' (server variable X_FORWARDED_PROTO). To use a different proxy request header use the corresponding server variable name as the [option] parameter. If using a proxy header variable the value from the proxy header should be either 'http' or 'https'.

Returns: string | null

host($option = null, $trusted_proxies = 'trust local', array $allowed_hosts = null)

Return the host value (domain name) for the request. If the host value contains a port number (for example 'site:8080' then it will be included with the host in return value). If the web server is behind a proxy server (for example a load balancer) then optional parameters allow for the host to be safely read from a proxy request header. If not using a proxy server then functions rootDir() and rootUrl() can be used to easily obtain needed URLs for the hosted site instead of using this function.

For reading proxy headers functions clientIp(), protocol(), host(), and port() all share similar parameters; refer to clientIp() documentation for detailed comments on the options. For host() if the [option] parameter is set to 'from proxy' then the value is read from the request header 'X-Forwarded-Host' (server variable X_FORWARDED_HOST). To use a different proxy request header use the corresponding server variable name as the [option] parameter.

For proxy server values an optional array of allowed hosts can be defined for validation using the [allowed_host] parameter. If the array is defined and the proxy host does not match then an exception is thrown. This can help prevent attacks when using a proxy server that specifies a different domain from the actual web server. Values in the array are matched to the host based on an exact match (case-insensitive) or can also be matched using one of two wildcard card characters: [*] which matches to one or more of any character and [#] which matches to a numeric value of digits.

[$allowed_hosts] Examples:
    'domain.tld'   - matches [domain.tld] and [DOMAIN.TLD] but not [www.domain.tld]
    '*.domain.tld' - matches [sub.domain.tld] and [sub. sub2.domain.tld] but not [domain.tld]
    'Domain.tld:#' - matches [domain.tld:8080]

Returns: string | null

port($option = null, $trusted_proxies = 'trust local')

Return the port number for the request. In most cases the end user would connect to a server using port 80 for HTTP and port 443 for secure HTTPS requests. Other port numbers may be used in development or on server environments. If the web server is behind a proxy server (for example a load balancer) then optional parameters allow for the port number to be safely read from a proxy request header. If not using a proxy server then functions rootDir() and rootUrl() can be used to easily obtain needed URLs for the hosted site instead of using this function.

For reading proxy headers functions clientIp(), protocol(), host(), and port() all share similar parameters; refer to clientIp() documentation for detailed comments on the options. For port() if the [option] parameter is set to 'from proxy' then the value is read from the request header 'X-Forwarded-Port' (server variable X_FORWARDED_PORT). To use a different proxy request header use the corresponding server variable name as the [option] parameter.

Returns: int

serverIp()

Return the IP Address that the Web Server is running from. When running on localhost or using PHP's Built-in Development Web Server this function will likely return '127.0.0.1' (IPv4) or '::1' (IPv6) and if running a PHP Script from the command line without a web server then this function will likely return null. For default Apache installations this function will get the IP Address from the server variable SERVER_ADDR and for default IIS installations this function will get the IP Address from the server variable LOCAL_ADDR. To get the Network IP Address of the Computer see the function [FastSitePHP\Net\Config->networkIp()].

Returns: string | null

isLocal()

Return true if the request is running from localhost '127.0.0.1' (IPv4) or '::1' (IPv6) and if the web server software is also running on localhost. This function can be used to show or hide specific site features for developers or administrators. This function would likely always be safe to call as it does not use IP Addresses from a proxy server however it is possible that a misconfigured sever or server code that overwrites server variables could provide incorrect info. If using this function make sure to test the site in various environments to see that it behaves as expected. The reference link provides an example of how a misconfigured server can cause errors with server software thinking its running in localhost when it's not. In regards to the reference link this function would not have failed as it's checking both Client and Server IP Addresses.

Returns: bool

accept($mime_type = null)

Parse the 'Accept' Request Header into an array or if an optional parameter is specified then check if the 'Accept' Header contains the specified MIME Type and return true or false. See also comments for the function [acceptLanguage()] because all [accept*()] functions have similar behavior.

Returns: array | bool

acceptCharset($character_encoding = null)

Parse the 'Accept-Charset' Request Header into an array or if an optional parameter is specified then check if the 'Accept-Charset' Header contains the specified Character Encoding and return true or false. See also comments for the function [acceptLanguage()] because all [accept*()] functions have similar behavior.

NOTE - this header is no longer commonly used and for web browsers and it is safe for servers to assume that UTF-8 is the accepted character encoding method.

Returns: array | bool

acceptEncoding($content_encoding = null)

Parse the 'Accept-Encoding' Request Header into an array or if an optional parameter is specified then check if the 'Accept-Encoding' Header contains the specified Content Encoding and return true or false. See also comments for the function [acceptLanguage()] because all [accept*()] functions have similar behavior.

Returns: array | bool

acceptLanguage($language = null)

For HTTP there are several standard 'Accept*' Request Headers that can be used for content negotiation by a web server to determine how to respond.

Parse the 'Accept-Language' Request Header into an array or if an optional parameter is specified then check if the 'Accept-Language' Header contains the specified Language and return true or false.

Example:
    'Accept-Language' Header Value = 'ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4'

    acceptLanguage():
    returns array(
        array('value' => 'ru-RU', 'quality' => null),
        array('value' => 'ru',    'quality' => 0.8),
        array('value' => 'en-US', 'quality' => 0.6),
        array('value' => 'en',    'quality' => 0.4),
    );

    acceptLanguage('en'): true
    acceptLanguage('de'): false

Returns: array | bool