Negociação de Conteúdo HTTP

Guilherme Nascimento
3 min readApr 17, 2020

Em HTTP a negociação de conteúdo é o mecanismo que é usado para servir diferentes representações de um recurso no mesmo URI, de modo que o agente do usuário pode especificar quais são os mais adequados para o usuário (por exemplo, qual idioma de um documento, qual formato de imagem, ou qual codificação de conteúdo), veja:

Para usar a negociação de conteúdo, coloque esta classe Inphinit\Experimental\Http\Negotiation em seu script, assim:

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

Verificar negociação de codificação pelo q-factor (q-value)

Para verificar os idiomas suportados enviados por requisições HTTP (do cabeçalho Accept-Language:), exemplo:

<?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>';
});

Para verificar os charsets suportados enviados por requisições HTTP (do cabeçalho Accept-Charset:), exemplo:

<?php
use Inphinit\Experimental\Http\Negotiation;
$negotiation = new Negotiation;$charsets = $negotiation->acceptCharset();print_r($charsets);

Para verificar os codificações de documento suportados enviados por requisições HTTP (do cabeçalho Accept-Encoding:), exemplo:

<?php
use Inphinit\Experimental\Http\Negotiation;
$negotiation = new Negotiation;$encodings = $negotiation->acceptEncoding();print_r($encodings);

Para verificar os tipos de documentos suportados enviados por requisições HTTP (do cabeçalho Accept:), exemplo:

<?php
use Inphinit\Experimental\Http\Negotiation;
$negotiation = new Negotiation;$types = $negotiation->accept();print_r($types);

Retornando apenas o valor principal

Detecta a language principal enviada pelas requisições HTTP (do cabeçalho Accept-Language:), exemplo:

<?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>';
});

Detecta a charset principal enviada pelas requisições HTTP (do cabeçalho Accept-Charset:), exemplo:

<?php
use Inphinit\Experimental\Http\Negotiation;
$negotiation = new Negotiation;$charset = $negotiation->getCharset();var_dump($charset);

Detecta a encoding principal enviada pelas requisições HTTP (do cabeçalho Accept-Encoding:), exemplo:

<?php
use Inphinit\Experimental\Http\Negotiation;
$negotiation = new Negotiation;$encoding = $negotiation->getEncoding();var_dump($encoding);

Detecta o tipo de documento principal enviada pelas requisições HTTP (do cabeçalho Accepted:), exemplo:

<?php
use Inphinit\Experimental\Http\Negotiation;
$negotiation = new Negotiation;$contentType = $negotiation->getAccept();var_dump($contentType);

Como obter a negociação de conteúdo por cabeçalhos personalizados

Para criar cabeçalhos Accept-* não padrão (ou cabeçalhos experimentais), se enviar uma solicitação HTTP assim:

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

Pode pegar os resultados usando Inphinit\Experimental\Http\Negotiation::header, exemplo:

<?php
use Inphinit\Experimental\Http\Negotiation;
$negotiation = new Negotiation;$charsets = $negotiation->header('Accept-Foo');print_r($charsets);

Usando q-factor para outros propósitos

Para usar q-factor/q-value para outros propósitos use o método estático Inphinit\Experimental\Http\Negotiation::qFactor, exemplo:

<?php
use Inphinit\Experimental\Http\Negotiation;
$qfactor = Negotiation::qFactor('Foo,Bar,Baz;q=0.1');print_r($qfactor);

Outro exemplo:

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

Ordenando

São 3 constantes, Inphinit\Experimental\Http\Negotiation::LOW e Inphinit\Experimental\Http\Negotiation::HIGH são usadas para ordenar e a constante Inphinit\Experimental\Http\Negotiation::ALL é usada para pegar todos resultados em um simples array.

Nota: Inphinit\Experimental\Http\Negotiation::HIGH é padrão nos seguintes métodos:

Do menor para o maior:

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

Exemplo com o método qFactor:

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

Retorna algo como:

Array
(
[0] => Array
(
[value] => Baz
[qfactor] => 0.8
)
[1] => Array
(
[value] => Bar
[qfactor] => 0.9
)
[2] => Array
(
[value] => Foo
[qfactor] => 1
)
)

Retorna os idiomas suportados em um array simples:

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

Retorna algo como:

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

Exemplo com o método qFactor:

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

Usando a classe Negotiation com outros recursos/fontes

Exemplo com um 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);

--

--