J'ai une image $file
(par exemple ../image.jpg
)
qui a un type mime $type
Comment puis-je le sortir sur le navigateur?
$file = '../image.jpg';
$type = 'image/jpeg';
header('Content-Type:'.$type);
header('Content-Length: ' . filesize($file));
readfile($file);
Si vous avez la liberté de configurer vous-même votre serveur Web, des outils tels que mod_xsendfile (pour Apache) sont considérablement mieux que de lire et d’imprimer le fichier en PHP. Votre code PHP ressemblerait à ceci:
header("Content-type: $type");
header("X-Sendfile: $file"); # make sure $file is the full path, not relative
exit();
mod_xsendfile récupère l'en-tête X-Sendfile et envoie le fichier au navigateur lui-même. Cela peut faire une réelle différence en termes de performances, en particulier pour les gros fichiers. La plupart des solutions proposées lisent l'intégralité du fichier en mémoire, puis l'impriment. Cela convient pour un fichier image de 20 Ko, mais si vous avez un fichier TIFF de 200 Mo, vous aurez inévitablement des problèmes.
$file = '../image.jpg';
if (file_exists($file))
{
$size = getimagesize($file);
$fp = fopen($file, 'rb');
if ($size and $fp)
{
// Optional never cache
// header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
// header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
// header('Pragma: no-cache');
// Optional cache if not changed
// header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($file)).' GMT');
// Optional send not modified
// if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) and
// filemtime($file) == strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']))
// {
// header('HTTP/1.1 304 Not Modified');
// }
header('Content-Type: '.$size['mime']);
header('Content-Length: '.filesize($file));
fpassthru($fp);
exit;
}
}
header('Content-type: image/jpeg');
readfile($image);
Essaye ça:
<?php
header("Content-type: image/jpeg");
readfile("/path/to/image.jpg");
exit(0);
?>
(Étendre la réponse acceptée ...)
J'avais besoin de:
jpg
image et une animation gif
, et, J'ai accompli cela en créant un fichier "secondaire" .htaccess
dans le sous-dossier où se trouvent les images.
Le fichier ne contient qu'une seule ligne:
AddHandler application/x-httpd-lsphp .jpg .jpeg .gif
Dans le même dossier, j'ai placé les deux fichiers d'image "d'origine" (nous les appellerons orig.jpg
et orig.gif
), ainsi que deux variantes du script [simplifié] ci-dessous (enregistrées en tant que myimage.jpg
et myimage.gif
) ...
<?php
error_reporting(0); //hide errors (displaying one would break the image)
//get user IP and the pseudo-image's URL
if(isset($_SERVER['REMOTE_ADDR'])) {$ip =$_SERVER['REMOTE_ADDR'];}else{$ip= '(unknown)';}
if(isset($_SERVER['REQUEST_URI'])) {$url=$_SERVER['REQUEST_URI'];}else{$url='(unknown)';}
//log the visit
require_once('connect.php'); //file with db connection info
$conn = new mysqli($servername, $username, $password, $dbname);
if (!$conn->connect_error) { //if connected then save mySQL record
$conn->query("INSERT INTO imageclicks (image, ip) VALUES ('$url', '$ip');");
$conn->close(); //(datetime is auto-added to table with default of 'now')
}
//display the image
$imgfile='orig.jpg'; // or 'orig.gif'
header('Content-Type: image/jpeg'); // or 'image/gif'
header('Content-Length: '.filesize($imgfile));
header('Cache-Control: no-cache');
readfile($imgfile);
?>
Les images sont rendues (ou animées) normalement et peuvent être appelées de n'importe quelle manière habituelle pour les images (comme une balise <img>
) et enregistreront un enregistrement de l'adresse IP visitée, tout en étant invisible pour l'utilisateur.
Vous pouvez utiliser finfo
(PHP 5.3+) pour obtenir le bon type MIME.
$filePath = 'YOUR_FILE.XYZ';
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$contentType = finfo_file($finfo, $filePath);
finfo_close($finfo);
header('Content-Type: ' . $contentType);
readfile($filePath);
PS: vous n'avez pas à spécifier Content-Length
, Apache le fera pour vous.
Pour le prochain gars ou fille qui rencontre ce problème, voici ce qui a fonctionné pour moi:
ob_start();
header('Content-Type: '.$mimetype);
ob_end_clean();
$fp = fopen($fullyQualifiedFilepath, 'rb');
fpassthru($fp);
exit;
Vous avez besoin de tout cela, et seulement de cela. Si votre type MIME varie, jetez un oeil à mime_content_type de PHP ($ filepath)
<?php $data=file_get_contents(".../image.jpg" );header("Content-type: image/png"); echo $data; ?>
La première étape consiste à récupérer l'image depuis un emplacement particulier, puis à la stocker dans une variable à cette fin, nous utilisons la fonction functio file_get_contents () avec la destination comme paramètre. Ensuite, nous définissons le type de contenu de la page de sortie en tant que type d'image à l'aide du fichier d'en-tête. Enfin, nous imprimons le fichier récupéré en utilisant echo.
<?php
header("Content-Type: $type");
readfile($file);
C'est la version courte. Il y a quelques petites choses supplémentaires que vous pouvez faire pour rendre les choses plus agréables, mais cela fonctionnera pour vous.
Vous pouvez utiliser header pour envoyer le type de contenu approprié:
header('Content-Type: ' . $type);
Et readfile
pour afficher le contenu de l'image:
readfile($file);
Et peut-être que (probablement pas nécessaire, mais juste au cas où), vous devrez aussi envoyer l'en-tête Content-Length:
header('Content-Length: ' . filesize($file));
Remarque: assurez-vous de ne rien produire d'autre que vos données d'image (sans espace, par exemple), sinon l'image ne sera plus valide.