This is done using Content negotiation using header Accept:
, as I explained in this answer:
In Chromium, Opera and other browsers based on Chromium has support for webp
so the header is passed like this by the browser when requesting the page:
GET /arquivos/ids/8043120-430-430/image-14d749d28e68b73ea65d4832318ba6d6.jpg?v=636408381268700000 HTTP/1.1
Host: shopfacil.vteximg.com.br
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36 OPR/51.0.2830.26
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
But when you access via Firefox for not having webp support it will be accessed via this way probably, see that in Accept:
has image/webp
:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,**image/webp**,image/apng,*/*;q=0.8
Firefox
The browser thus requests:
GET /arquivos/ids/8043120-430-430/image-14d749d28e68b73ea65d4832318ba6d6.jpg?v=636408381268700000 HTTP/1.1
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
Connection:keep-alive
Host: shopfacil.vteximg.com.br
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0
Of course in PHP there is nothing native for the q-factor , but there are libs via PEAR as
Or use the script for this answer but set it to the Accept:
header (which is used to mime -type), for example:
function AcceptHeader($name)
{
$qvalues = array(); // used to store values
if (empty($_SERVER[$name]) === false) {
$result = preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $_SERVER[$name], $parsed);
if ($result && count($parsed[1])) {
$qvalues = array_combine($parsed[1], $parsed[4]);
// Define o valor para tipos sem q-value definido
foreach ($qvalues as &$val) {
if ($val === '') {
$val = 1;
}
}
// sort list based on value
arsort($qvalues, SORT_NUMERIC);
}
}
return $qvalues;
}
Example to get the header of type requested by the browser:
$tipos = AcceptHeader('HTTP_ACCEPT');
Example for languages supported by the browser:
$idiomas = AcceptHeader('HTTP_ACCEPT_LANGUAGE');
But since the focus is mime-type, then you should use something like this:
$tipos = AcceptHeader('HTTP_ACCEPT');
//Filtra somente imagens
$tipos = array_filter($tipos, function($header, $qvalue) {
return stripos($header, 'image/') === 0;
}, ARRAY_FILTER_USE_BOTH);
//Pega a primeira chave
$tipos = reset($tipos);
$tipo = key($tipos);
//Se contiver imagem/webp
if ($tipo == 'image/webp') {
readfile('images/webp/image.webp');
} else {
readfile('images/jpg/image.jpg');
}
Of course it may be a lot simpler yet, this is just a suggestion of how to deliver according to browser preference or user content type, but you can decide to just check if there is support independent of the priority of the q-factor using
preg_match
and regex , like this:
if (isset($_SERVER['HTTP_ACCEPT']) && preg_match('#[\s,;]image/webp[\s,;]#', $_SERVER['HTTP_ACCEPT'])) {
readfile('images/webp/image.webp');
} else {
readfile('images/jpg/image.jpg');
}