Ok, j'ai donc un fichier index.php qui doit traiter de nombreux types de fichiers différents. comment deviner le type de fichier basé sur le REQUEST_URI
.
Si je demande http://site/image.jpg
, et toutes les demandes redirigent via index.php, qui ressemble à ceci
<?php
include('/www/site'.$_SERVER['REQUEST_URI']);
?>
Comment pourrais-je faire fonctionner cela correctement?
Dois-je tester en fonction de l'extension du fichier demandé, ou existe-t-il un moyen d'obtenir le type de fichier?
Si vous êtes sûr de ne travailler qu'avec des images, vous pouvez consulter le getimagesize () exif_imagetype () PHP, qui tente de renvoyer le type mime de l'image.
Si cela ne vous dérange pas les dépendances externes, vous pouvez également consulter l'excellente bibliothèque getID qui peut déterminer le type MIME de nombreux types de fichiers différents.
Enfin, vous pouvez vérifier la fonction mime_content_type () - mais elle est déconseillée pour l'extension Fileinfo PECL.
mime_content_type () est obsolète, vous ne pourrez donc pas compter sur son fonctionnement à l'avenir. Il y a une extension PECL "fileinfo", mais je n'ai pas entendu de bonnes choses à ce sujet.
Si vous utilisez un serveur * nix, vous pouvez effectuer les opérations suivantes, ce qui a bien fonctionné pour moi:
$file = escapeshellarg( $filename );
$mime = Shell_exec("file -bi " . $file);
$filename should probably include the absolute path.
function get_mime($file) {
if (function_exists("finfo_file")) {
$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
$mime = finfo_file($finfo, $file);
finfo_close($finfo);
return $mime;
} else if (function_exists("mime_content_type")) {
return mime_content_type($file);
} else if (!stristr(ini_get("disable_functions"), "Shell_exec")) {
// http://stackoverflow.com/a/134930/1593459
$file = escapeshellarg($file);
$mime = Shell_exec("file -bi " . $file);
return $mime;
} else {
return false;
}
}
Pour moi, rien de tout cela ne fonctionne - mime_content_type
est obsolète, finfo
n'est pas installé et Shell_exec
n'est pas autorisé.
En fait, je me suis marre du manque de méthodes de reniflement MIME standard en PHP. Installez fileinfo ... Utilisez des fonctions obsolètes ... Oh ces travaux, mais uniquement pour les images! J'en ai eu marre de ça, alors j'ai fait des recherches et trouvé la WHATWG Mimesniffing spec - Je pense que c'est encore une ébauche de spécification.
Quoi qu'il en soit, en utilisant cette spécification, j'ai pu implémenter un mimesniffer en PHP. La performance n'est pas un problème. En fait, sur mon humble machine, j'ai pu ouvrir et renifler des milliers de fichiers avant l'expiration du délai PHP.
Voici la classe MimeReader .
require_once("MimeReader.php");
$mime = new MimeReader(<YOUR FILE PATH>);
$mime_type_string = $mime->getType(); // "image/jpeg" etc.
Si vous travaillez uniquement avec des images et que vous avez besoin d'un type MIME (par exemple pour les en-têtes), alors c'est la réponse la plus rapide et la plus directe:
$file = 'path/to/image.jpg';
$image_mime = image_type_to_mime_type(exif_imagetype($file));
Il produira un vrai type de mime d'image même si vous renommez votre fichier image
Vous pouvez utiliser finfo pour y parvenir à partir de PHP 5.3:
<?php
$info = new finfo(FILEINFO_MIME_TYPE);
echo $info->file('myImage.jpg');
// prints "image/jpeg"
L'indicateur FILEINFO_MIME_TYPE est facultatif; sans cela, vous obtenez une chaîne plus détaillée pour certains fichiers; (apparemment, certains types d'images renvoient des informations sur la taille et la profondeur des couleurs). L'utilisation de l'indicateur FILEINFO_MIME renvoie le type MIME et l'encodage si disponible (par exemple, image/png; charset = binary ou text/x-php; charset = us-ascii). Voir ce site pour plus d'informations.
mime_content_type()
semble être le chemin à parcourir, malgré les commentaires ci-dessus disant qu'il est obsolète. Ce n'est pas - ou du moins cette incarnation de mime_content_type()
n'est pas déconseillée, selon http://php.net/manual/en/function.mime-content-type.php . Il fait partie de l'extension FileInfo, mais la documentation PHP nous indique maintenant qu'il est activé par défaut à partir de PHP 5.3.0.
Selon le manuel php, la fonction finfo-file est le meilleur moyen de le faire. Cependant, vous devrez installer l'extension FileInfo PECL.
Si l'extension n'est pas une option, vous pouvez utiliser la fonction obsolète mime_content_type .
si vous ne traitez qu'avec des images, vous pouvez utiliser la fonction [getimagesize()][1]
qui contient toutes sortes d'informations sur l'image, y compris le type.
Une approche plus générale serait d'utiliser l'extension FileInfo de PECL. La documentation PHP pour cette extension peut être trouvée sur: http://us.php.net/manual/en/ref.fileinfo.php
Certaines personnes ont de sérieuses plaintes à propos de cette extension ... donc si vous rencontrez des problèmes graves ou ne pouvez pas installer l'extension pour une raison quelconque, vous voudrez peut-être vérifier la fonction obsolète mime_content_type()
Le mime de n'importe quel fichier sur votre serveur peut être obtenu avec ceci
<?php
function get_mime($file_path){
$finfo = new finfo(FILEINFO_MIME_TYPE);
$type = $finfo->file(file_path);
}
$mime = get_mime('path/to/file.ext');
j'ai obtenu de très bons résultats en utilisant une fonction utilisateur de http://php.net/manual/de/function.mime-content-type.php @ '' john dot howard à prismmg dot com 26- Oct-2009 03:43 ''
function get_mime_type($filename, $mimePath = '../etc') { ...
qui n'utilise pas la fonction finfo, exec ou obsolète
fonctionne bien aussi avec des ressources distantes!
Si vous exécutez Linux et que vous avez l'extension, vous pouvez simplement lire le type MIME à partir de /etc/mime.types en créant un tableau de hachage. Vous pouvez ensuite stocker cela en mémoire et appeler simplement la clé MIME par tableau :)
/**
* Helper function to extract all mime types from the default Linux /etc/mime.types
*/
function get_mime_types() {
$mime_types = array();
if (
file_exists('/etc/mime.types') &&
($fh = fopen('/etc/mime.types', 'r')) !== false
) {
while (($line = fgets($fh)) !== false) {
if (!trim($line) || substr($line, 0, 1) === '#') continue;
$mime_type = preg_split('/\t+/', rtrim($line));
if (
is_array($mime_type) &&
isset($mime_type[0]) && $mime_type[0] &&
isset($mime_type[1]) && $mime_type[1]
) {
foreach (explode(' ', $mime_type[1]) as $ext) {
$mime_types[$ext] = $mime_type[0];
}
}
}
fclose($fh);
}
return $mime_types;
}
Je ne l'ai pas utilisé, mais il y a extension PECL pour obtenir le type MIME d'un fichier. La documentation officielle pour cela se trouve dans le manuel .
Selon vos besoins, une extension de fichier peut être correcte, mais elle n'est pas incroyablement fiable car elle est si facilement changée.