J'essaie de mettre en place une fonction qui reçoit un chemin de fichier, identifie ce qu'il est, définit les en-têtes appropriés et le sert comme le ferait Apache.
La raison pour laquelle je fais cela est que j'ai besoin d'utiliser PHP pour traiter certaines informations sur la requête avant de servir le fichier.
La vitesse est essentielle
virtual() n'est pas une option
Doit travailler dans un environnement d'hébergement partagé où l'utilisateur n'a aucun contrôle sur le serveur web (Apache/nginx, etc.)
Voici ce que j'ai obtenu jusqu'à présent :
File::output($path);
<?php
class File {
static function output($path) {
// Check if the file exists
if(!File::exists($path)) {
header('HTTP/1.0 404 Not Found');
exit();
}
// Set the content-type header
header('Content-Type: '.File::mimeType($path));
// Handle caching
$fileModificationTime = gmdate('D, d M Y H:i:s', File::modificationTime($path)).' GMT';
$headers = getallheaders();
if(isset($headers['If-Modified-Since']) && $headers['If-Modified-Since'] == $fileModificationTime) {
header('HTTP/1.1 304 Not Modified');
exit();
}
header('Last-Modified: '.$fileModificationTime);
// Read the file
readfile($path);
exit();
}
static function mimeType($path) {
preg_match("|\.([a-z0-9]{2,4})$|i", $path, $fileSuffix);
switch(strtolower($fileSuffix[1])) {
case 'js' :
return 'application/x-javascript';
case 'json' :
return 'application/json';
case 'jpg' :
case 'jpeg' :
case 'jpe' :
return 'image/jpg';
case 'png' :
case 'gif' :
case 'bmp' :
case 'tiff' :
return 'image/'.strtolower($fileSuffix[1]);
case 'css' :
return 'text/css';
case 'xml' :
return 'application/xml';
case 'doc' :
case 'docx' :
return 'application/msword';
case 'xls' :
case 'xlt' :
case 'xlm' :
case 'xld' :
case 'xla' :
case 'xlc' :
case 'xlw' :
case 'xll' :
return 'application/vnd.ms-excel';
case 'ppt' :
case 'pps' :
return 'application/vnd.ms-powerpoint';
case 'rtf' :
return 'application/rtf';
case 'pdf' :
return 'application/pdf';
case 'html' :
case 'htm' :
case 'php' :
return 'text/html';
case 'txt' :
return 'text/plain';
case 'mpeg' :
case 'mpg' :
case 'mpe' :
return 'video/mpeg';
case 'mp3' :
return 'audio/mpeg3';
case 'wav' :
return 'audio/wav';
case 'aiff' :
case 'aif' :
return 'audio/aiff';
case 'avi' :
return 'video/msvideo';
case 'wmv' :
return 'video/x-ms-wmv';
case 'mov' :
return 'video/quicktime';
case 'zip' :
return 'application/zip';
case 'tar' :
return 'application/x-tar';
case 'swf' :
return 'application/x-shockwave-flash';
default :
if(function_exists('mime_content_type')) {
$fileSuffix = mime_content_type($path);
}
return 'unknown/' . trim($fileSuffix[0], '.');
}
}
}
?>
11 votes
Pourquoi tu ne laisses pas Apache faire ça ? Ce sera toujours considérablement plus rapide que de lancer l'interpréteur PHP...
4 votes
Je dois traiter la demande et stocker certaines informations dans la base de données avant de sortir le fichier.
3 votes
Puis-je suggérer un moyen d'obtenir l'extension sans les expressions régulières plus coûteuses :
$extension = end(explode(".", $pathToFile))
ou vous pouvez le faire avec substr et strrpos :$extension = substr($pathToFile, strrpos($pathToFile, '.'))
. En outre, comme solution de rechange àmime_content_type()
vous pouvez essayer un appel système :$mimetype = exec("file -bi '$pathToFile'", $output);
0 votes
Que voulez-vous dire par le plus rapide ? Le temps de téléchargement le plus rapide ?