This is done using Content negotiation using the header Accept:
, as I explained in this reply:
In Chrome, Opera and other Chromium-based browsers have support for webp
so the header is passed like this by the browser when ordering 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 accessing via Firefox for not having webp support will be accessed via so probably, see that on Accept:
has image/webp
:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,**image/webp**,image/apng,*/*;q=0.8
Already in the Firefox browser so 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 to the q-factor, but there are libs via PEAR as
Or use the script of this answer but adjust it to the header Accept:
(which is used for 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 catch type header requested by browser:
$tipos = AcceptHeader('HTTP_ACCEPT');
Example for obtaining browser-supported languages:
$idiomas = AcceptHeader('HTTP_ACCEPT_LANGUAGE');
But since the focus is mime-type, then you should use more or less 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 can be much simpler still, all this above is just a suggestion of how to deliver as preferred by the browser or user the type of content, but you can choose to just decide to check if there is support independent of the priority of q-factor using preg_match
and regex, thus:
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');
}
your image.jpg? v=123 What is the problem?
– Ivan Ferrer