Negociação de conteúdo HTTP
A negociação de conteúdo é o mecanismo usado para fornecer diferentes representações de um recurso para o mesmo URI (por exemplo, idioma, formato ou codificação).
Quando um cliente solicita um recurso, ele o faz usando uma URL. Com base nessa URL, o servidor seleciona uma das variantes disponíveis — chamadas representações — e retorna a representação apropriada para o cliente. Tanto o recurso em si quanto cada uma de suas representações possuem suas próprias URLs. A negociação de conteúdo define como o servidor escolhe qual representação retornar quando o recurso é solicitado.
A especificação HTTP/1.1 define um conjunto de cabeçalhos de solicitação padrão que iniciam a negociação de conteúdo orientada pelo servidor, como Accept, Accept-Encoding, e Accept-Language.
Constantes
| Constante | Descrição |
|---|---|
Negotiation::ALL |
Obter todos os valores de um cabeçalho Accept (sem o fator Q) |
Negotiation::LOW |
Ordene os valores no cabeçalho do menor para o maior pelos fatores q. |
Negotiation::HIGH |
Ordene os valores no cabeçalho do maior para o menor pelos fatores q. |
API
| Método | Uso equivalente | Descrição |
|---|---|---|
contentTypes(int $sort = self::HIGH): array |
...->entries('accept', ...) |
Retorna todos valores do header Accept, ordenado pelo segundo parametro |
encodings(int $sort = self::HIGH): array |
...->entries('accept-encoding', ...) |
Retorna todos valores do header Accept-Encondig, ordenado pelo segundo parametro |
languages(int $sort = self::HIGH): array |
...->entries('accept-language', ...) |
Retorna todos valores do header Accept-Language, ordenado pelo segundo parametro |
topContentType(): string|mixed |
...->top('accept-encondig') |
Retorna tipo de documento prioritário no cabeçalho Accept |
topEncondig(): string|mixed |
...->top('accept-encondig') |
Retorna codificação prioritária no cabeçalho Accept-Encondig |
topLanguage(): string|mixed |
...->top('accept-language') |
Retorna idioma prioritário no cabeçalho Accept-Language |
fromString(string $str): Negotiation |
Cria uma instância de Negotiation baseada em uma string |
|
qFactor($value, $sort = self::HIGH): array |
Analisa e obtêm os itens ordenados de um único valor |
Cabeçalho Accept
Se você tiver uma solicitação HTTP como:
GET /foo/bar HTTP/1.1
Accept: image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5
O exemplo a seguir retornará image/avif, que é o valor com o maior q-value:
use Inphinit\Http\Negotiation;
$negotiation = new Negotiation();
echo $negotiation->getContentType();
Retorna todos os valores em Accept ordenados do maior para o menor q-value como uma matriz:
use Inphinit\Http\Negotiation;
$negotiation = new Negotiation();
print_r($negotiation->contentTypes(Negotiation::HIGH));
Saída:
Array
(
[image/avif] => 1
[image/webp] => 1
[image/png] => 1
[image/svg+xml] => 1
[image/*] => 0.8
[*/*] => 0.5
)
Retorna todos os valores em Accept ordenados do menor para o maior q-value como uma matriz:
use Inphinit\Http\Negotiation;
$negotiation = new Negotiation();
print_r($negotiation->contentTypes(Negotiation::LOW));
Saída:
Array
(
[*/*] => 0.5
[image/*] => 0.8
[image/svg+xml] => 1
[image/png] => 1
[image/webp] => 1
[image/avif] => 1
)
Cabeçalho Accept-Encoding
Se você tiver uma solicitação HTTP como:
GET /foo/bar HTTP/1.1
Accept-Encoding: br;q=1.0, gzip;q=0.8, *;q=0.1
O exemplo a seguir retornará br, que é o valor com o maior q-value:
use Inphinit\Http\Negotiation;
$negotiation = new Negotiation();
echo $negotiation->getEncoding();
Retorna todos valores em Accept-Encodings ordenados do maior para o menor q-value como uma matriz:
use Inphinit\Http\Negotiation;
$negotiation = new Negotiation();
print_r($negotiation->encodings(Negotiation::HIGH));
Saída:
Array
(
[br] => 1
[gzip] => 0.8
[*] => 0.1
)
Retorna todos valores em Accept-Encoding ordenados do menor para o maior q-value como uma matriz:
use Inphinit\Http\Negotiation;
$negotiation = new Negotiation();
print_r($negotiation->encodings(Negotiation::LOW));
Saída:
Array
(
[*] => 0.1
[gzip] => 0.8
[br] => 1
)
Cabeçalho Accept-Language
Se você tiver uma solicitação HTTP como:
GET /foo/bar HTTP/1.1
Accept-Language: fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5
O exemplo a seguir retornará fr-CH, que é o valor com o maior q-value:
use Inphinit\Http\Negotiation;
$negotiation = new Negotiation();
echo $negotiation->getLanguage();
Retorna todos valores em Accept-Language ordenados do maior para o menor q-value como uma matriz:
use Inphinit\Http\Negotiation;
$negotiation = new Negotiation();
print_r($negotiation->languages(Negotiation::HIGH));
Saída:
Array
(
[fr-CH] => 1
[fr] => 0.9
[en] => 0.8
[de] => 0.7
[*] => 0.5
)
Retorna todos valores em Accept-Language ordenados do menor para o maior q-value como uma matriz:
use Inphinit\Http\Negotiation;
$negotiation = new Negotiation();
print_r($negotiation->languages(Negotiation::LOW));
Saída:
Array
(
[*] => 0.5
[de] => 0.7
[en] => 0.8
[fr] => 0.9
[fr-CH] => 1
)
Outros cabeçalhos com valores de qualidade
Exemplo de solicitação:
GET /foo/bar HTTP/1.1
TE: gzip; q=1.0, deflate; q=0.8
Custom: foo, bar;q=0.9, baz;q=0.8, quux;q=0.7, waldo;q=0.5
Uso:
use Inphinit\Http\Negotiation;
$negotiation = new Negotiation();
$te = $negotiation->top('te', Negotiation::HIGH);
var_dump($te);
$te = $negotiation->entries('te', Negotiation::HIGH);
print_r($te);
$te = $negotiation->top('custom', Negotiation::HIGH);
var_dump($te);
$custom = $negotiation->entries('custom', Negotiation::HIGH);
print_r($custom);
Saída:
string(4) "gzip"
Array
(
[gzip] => 1
[deflate] => 0.8
)
string(3) "foo"
Array
(
[foo] => 1
[bar] => 0.9
[baz] => 0.8
[quux] => 0.7
[waldo] => 0.5
)
Analisando strings
Analisando cabeçalhos
O analisador sintático interno pode ser usado independentemente de requisições HTTP, permitindo sua reutilização em outros contextos ou até mesmo em implementações personalizadas de cliente-servidor. Exemplo:
$str = <<<EOT
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br, zstd
EOT;
$negotiation = Negotiation::fromString($str);
...
Analisando valores de qualidade
É possível analisar valores de qualidade (valores q ou fatores q) independentemente do contexto do cabeçalho, tornando seu uso bastante flexível:
$input = 'mesh/capsule;q=0.2,mesh/cube;q=0.9,mesh/cylinder;q=0.5,mesh/plane;q=0.4,mesh/quad;q=0.3,mesh/sphere;q=0.8';
$entries = Negotiation::qFactor($input, Negotiation::HIGH);
print_r($entries);
Saída:
Array
(
[mesh/cube] => 0.9
[mesh/sphere] => 0.8
[mesh/cylinder] => 0.5
[mesh/plane] => 0.4
[mesh/quad] => 0.3
[mesh/capsule] => 0.2
)