Skip to content

HTTP Content Negotiation

Guilherme Nascimento edited this page May 19, 2020 · 4 revisions

In HTTP, Content negotiation is the mechanism that is used for serving different representations of a resource at the same URI, so that the user agent can specify which is best suited for the user (for example, which language of a document, which image format, or which content encoding), see:

For use content negotiation put this Inphinit\Experimental\Http\Negotiation class in your script, like this:

<?php
use Inphinit\Experimental\Http\Negotiation;

Check content negotiation by q-factor (q-value)

For check supported languages send by HTTP requests (from Accept-Language: header), eg.:

<?php
use Inphinit\Routing\Route;
use Inphinit\Experimental\Http\Negotiation;

Route::set('GET', '/test', function () {
    $negotiation = new Negotiation;
    $langs = $negotiation->acceptLanguage();

    return '<pre>' . print_r($langs, true) . '</pre>';
});

For check supported charsets send by HTTP requests (from Accept-Charset: header), eg.:

<?php
use Inphinit\Experimental\Http\Negotiation;

$negotiation = new Negotiation;

$charsets = $negotiation->acceptCharset();

print_r($charsets);

For check supported document encodings send by HTTP requests (from Accept-Encoding: header), eg.:

<?php
use Inphinit\Experimental\Http\Negotiation;

$negotiation = new Negotiation;

$encodings = $negotiation->acceptEncoding();

print_r($encodings);

For check supported document types send by HTTP requests (from Accept: header), eg.:

<?php
use Inphinit\Experimental\Http\Negotiation;

$negotiation = new Negotiation;

$types = $negotiation->accept();

print_r($types);

Main supported

Detect main language supported (from Accept-Language: header), eg.:

<?php
use Inphinit\Routing\Route;
use Inphinit\Experimental\Http\Negotiation;

Route::set('GET', '/test', function () {
    $negotiation = new Negotiation;

    $lang = $negotiation->getLanguage();

    $lang = $lang ? substr($lang, 0, 2) : 'en';

    switch ($lang) {
        case 'pt':
            $msg = 'Olá mundo!';
            break;

        case 'es':
            $msg = '¡Hola Mundo!';
            break;

        default:
            $msg = 'Hello, world!';
            break;
    }

    return '<h1>' . $msg . '</h1>';
});

Detect main charset supported (from Accept-Charset: header), eg.:

<?php
use Inphinit\Experimental\Http\Negotiation;

$negotiation = new Negotiation;

$charset = $negotiation->getCharset();

var_dump($charset);

Detect main encoding supported (from Accept-Encoding: header), eg.:

<?php
use Inphinit\Experimental\Http\Negotiation;

$negotiation = new Negotiation;

$encoding = $negotiation->getEncoding();

var_dump($encoding);

Detect main document types supported (from Accept: header), eg.:

<?php
use Inphinit\Experimental\Http\Negotiation;

$negotiation = new Negotiation;

$contentType = $negotiation->getAccept();

var_dump($contentType);

Get content negotiation by custom headers

For create non standard Accept headers (or experimental headers), if send a HTTP request like this:

GET /dump HTTP/1.1
Host: localhost
Connection: keep-alive
Accept-Foo: Baz,Bar;q=0.9,FooBar;q=0.8

Can get results using Inphinit\Experimental\Http\Negotiation::header, eg.:

<?php
use Inphinit\Experimental\Http\Negotiation;

$negotiation = new Negotiation;

$charsets = $negotiation->header('Accept-Foo');

print_r($charsets);

Use q-factor for other purposes

For use q-factor/q-value for other purposes call this Inphinit\Experimental\Http\Negotiation::qFactor static method, eg.:

<?php
use Inphinit\Experimental\Http\Negotiation;

$qfactor = Negotiation::qFactor('Foo,Bar,Baz;q=0.1');

print_r($qfactor);

Other example:

$qfactor = Negotiation::qFactor('Foo,Bar;q=0.9,Baz;q=0.8');

print_r($qfactor);

Sort order

There are 3 constants, Inphinit\Experimental\Http\Negotiation::LOW and Inphinit\Experimental\Http\Negotiation::HIGH are used to sort, and Inphinit\Experimental\Http\Negotiation::ALL is used to get all results in a simple array.

Note Inphinit\Experimental\Http\Negotiation::HIGH is default in this methods:

Low to high:

$negotiation = new Negotiation;
$langs = $negotiation->languages(Negotiation::LOW);

Example with qFactor method:

$qfactor = Negotiation::qFactor('Foo,Bar;q=0.9,Baz;q=0.8', Negotiation::LOW);

Returns like this:

Array
(
    [0] => Array
        (
            [value] => Baz
            [qfactor] => 0.8
        )

    [1] => Array
        (
            [value] => Bar
            [qfactor] => 0.9
        )

    [2] => Array
        (
            [value] => Foo
            [qfactor] => 1
        )

)

Get supported languages in an simple array:

$negotiation = new Negotiation;
$langs = $negotiation->languages(Negotiation::ALL);

Returns like:

Array
(
    [0] => pt-BR
    [1] => pt
    [2] => en
    [3] => de
    [4] => *
)

Example with qFactor method:

$qfactor = Negotiation::qFactor('Foo,Bar;q=0.9,Baz;q=0.8', Negotiation::ALL);
Array
(
    [0] => Foo
    [1] => Bar
    [2] => Baz
)

Using Negotiation class with other resources

Example with array:

$negotiation = new Negotiation(array(
    'Accept' => 'text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8',
    'Accept-Language' => 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5',
    'Accept-Encoding' => 'deflate, gzip;q=1.0, *;q=0.5',
    'Accept-Charset' => 'utf-8, iso-8859-1;q=0.5',
    'Accept-Foo' => 'Baz,Bar;q=0.9,FooBar;q=0.8'
));

$types = $negotiation->types();
$langs = $negotiation->languages();
$charsets = $negotiation->charsets();
$encodings = $negotiation->encodings();

$foo = $negotiation->header('accept-foo');

var_dump($types, $langs, $charsets, $encodings, $foo);
Clone this wiki locally