In questo momento sto cercando di servire file CSS e JS da un server che non mi consente di abilitare mod_gzip
o mod_deflate
. Così ho scritto un piccolo script PHP per comprimere con GZIP e tornare all'utente.Come determinare la lunghezza del contenuto di un file gzip?
Esempio di codice:
$filename = "style.css";
if (!file_exists($filename) || !($info = stat($filename))) {
header("HTTP/1.1 404 Not Found");
die();
}
header("Date: ".gmdate("D, j M Y H:i:s e", time()));
header("Cache-Control: max-age=2592000");
header("Last-Modified: ".gmdate("D, j M Y H:i:s e", $info['mtime']));
header("Etag: ".sprintf("\"%x-%x-%x\"", $info['ino'], $info['size'], $info['mtime']));
header("Accept-Ranges: bytes");
header("Cache-Control: Expires ".gmdate("D, j M Y H:i:s e", $info['mtime']+2592000));
header("Content-Type: text/html");
ob_start("ob_gzhandler");
echo file_get_contents($filename);
ob_end_flush();
Sto avendo due problemi in questo momento. Il primo è che ho difficoltà a determinare la dimensione risultante del file compresso per informare il browser della lunghezza del contenuto. Normalmente, vorrei includere questa linea:
header("Content-Length: ".$info["size"]);
Ma, se lo faccio, il browser si blocca durante il tentativo di attendere ulteriori dati. C'è un modo per calcolare la dimensione totale? O dovrei ignorare questa direttiva header.
L'altro problema è che ogni volta che visualizzo questo file PHP in Firefox, tenta di farmi scaricare il risultato. In Chrome, mostra semplicemente come mi aspetterei. Eventuali suggerimenti?
Edit: Grazie a Soapbox, ho sostituito alla fine del codice con questo:
header("Content-Encoding: gzip");
$compressed = gzencode(file_get_contents($filename), 5);
header("Content-Length: ".strlen($compressed));
die($compressed);
Questa grande opera per il contenuto di lunghezza! Ma sto ancora scaricando Firefox per scaricare il file anziché visualizzarlo. :(
Edit Anche in questo caso: Ecco la fine del codice modificato, per gentile concessione di Cletus
// Start buffered output
ob_start();
// Check for gzip capability
if (stripos($_SERVER['HTTP_ACCEPT_ENCODING'], "gzip") !== false) {
ob_start("ob_gzhandler");
echo file_get_contents($filename);
ob_end_flush();
} else
echo file_get_contents($filename);
// Write the content length
header('Content-Length: '.ob_get_length());
ob_end_flush();
ho intenzione di iniziare una nuova domanda per capire il motivo per cui Firefox continua a cercare di. scarica il file.
Alcune delle intestazioni citate nelle risposte hanno alcuni errori; Il doppio Cache-Control, la linea con Cache-Control: Expires .... dovrebbe essere Expires: ... E Etag dovrebbe essere ETag. –