PHP und / oder der Server kümmern sich für Sie um die Länge des Inhalts.
Matthew Scharley
1
Der Inhaltslängen-Header dient zur Vereinfachung.
Emre Yazici
2
Aus irgendeinem Grund ist die Dateigröße für mich fehlgeschlagen, als ich versucht habe, über einen absoluten Pfad auf das Bild zuzugreifen. Daher habe ich diese Zeile kommentiert und der Code funktioniert einwandfrei.
Kiranvj
15
Es ist besser, Content-Length nicht zu verwenden, insbesondere wenn Sie GZip auf Ihrem Webserver aktiviert haben, da Sie dem Browser mitteilen, dass er mehr Bytes erwarten soll, als tatsächlich eintreffen, und das Warten auf eine Zeitüberschreitung abwartet. Dies kann schlimme Folgen haben, wenn z. B. JS auf das Ereignis wartet.
Coder
Stellen Sie sicher, dass "Content-Type" groß geschrieben ist. Ich bin gerade darauf
gestoßen,
32
Wenn Sie die Freiheit haben, Ihren Webserver selbst zu konfigurieren, sind Tools wie mod_xsendfile (für Apache) erheblich besser als das Lesen und Drucken der Datei in PHP. Ihr PHP-Code würde folgendermaßen aussehen:
header("Content-type: $type");
header("X-Sendfile: $file"); # make sure $file is the full path, not relativeexit();
mod_xsendfile nimmt den X-Sendfile-Header auf und sendet die Datei an den Browser selbst. Dies kann einen echten Leistungsunterschied bewirken, insbesondere bei großen Dateien. Die meisten der vorgeschlagenen Lösungen lesen die gesamte Datei in den Speicher und drucken sie dann aus. Das ist für eine 20-KByte-Bilddatei in Ordnung, aber wenn Sie eine 200-MByte-TIFF-Datei haben, treten Probleme auf.
@Michael via php.net Die Funktion getimagesize () bestimmt die Größe einer bestimmten Bilddatei und gibt die Abmessungen zusammen mit dem Dateityp und einer Textzeichenfolge für Höhe / Breite zurück, die in einem normalen HTML-IMG-Tag und dem entsprechenden HTTP-Inhalt verwendet werden sollen Art.
Das funktioniert bei mir! Ich habe es auf Code Igniter getestet. Wenn ich Readfile verwende, wird das Bild nicht angezeigt. Manchmal nur JPG anzeigen, manchmal nur große Datei. Aber nachdem ich es in "file_get_contents" geändert habe, bekomme ich den Geschmack und funktioniert !! Dies ist der Screenshoot:
Screenshot des "sicheren Bildes" aus der Datenbank
Protokollansichten eines jpgBildes und ein animiertesgif , und,
Stellen Sie sicher, dass die Bilder niemals zwischengespeichert werden (damit jede Ansicht protokolliert wird) .
auch behalten die ursprünglichen Dateierweiterungen .
Ich habe dies erreicht, indem ich eine "sekundäre" .htaccessDatei in dem Unterordner erstellt habe, in dem sich die Bilder befinden.
Die Datei enthält nur eine Zeile:
Im selben Ordner habe ich die beiden 'Original'-Bilddateien (wir nennen sie orig.jpgund orig.gif) sowie zwei Variationen des [vereinfachten] Skripts unten gespeichert (gespeichert als myimage.jpgund myimage.gif) ...
<?php
error_reporting(0); //hide errors (displaying one would break the image)//get user IP and the pseudo-image's URLif(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 visitrequire_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);
?>
Die Bilder werden normal gerendert (oder animiert) und können auf eine der normalen Arten für Bilder (wie ein <img>Tag) aufgerufen werden. Sie speichern eine Aufzeichnung der besuchenden IP, während sie für den Benutzer unsichtbar sind.
Das ist die Kurzversion. Es gibt ein paar zusätzliche kleine Dinge, die Sie tun können, um die Dinge schöner zu machen, aber das wird für Sie funktionieren.
Der erste Schritt besteht darin, das Bild von einem bestimmten Ort abzurufen und es dann in einer Variablen zu speichern. Zu diesem Zweck verwenden wir die Funktion file_get_contents () mit dem Ziel als Parameter. Als nächstes legen wir den Inhaltstyp der Ausgabeseite mithilfe der Header-Datei als Bildtyp fest. Schließlich drucken wir die abgerufene Datei mit Echo.
Hallo und willkommen bei Stack Overflow! Würde es Ihnen etwas ausmachen, Ihre Antwort mit einer Erklärung zu aktualisieren, warum Ihre Lösung funktioniert? Könnten Sie auch die Anführungszeichen aus Ihrer Antwort entfernen, da der Syntax-Textmarker dadurch alles als Zeichenfolgenliteral behandelt? Vielen Dank!
Michael Cordingley
Bitte teilen Sie einige Erklärungen. Warum haben Sie beispielsweise die Content-type: image/pngAusgabe eines JPG-Bildes festgelegt? Warum sollte die gesamte Datei in eine Variable eingelesen werden? Sollte nicht readfileeine viel bessere Speicherleistung haben?
<img>
Tags?Antworten:
$file = '../image.jpg'; $type = 'image/jpeg'; header('Content-Type:'.$type); header('Content-Length: ' . filesize($file)); readfile($file);
quelle
Wenn Sie die Freiheit haben, Ihren Webserver selbst zu konfigurieren, sind Tools wie mod_xsendfile (für Apache) erheblich besser als das Lesen und Drucken der Datei in PHP. Ihr PHP-Code würde folgendermaßen aussehen:
header("Content-type: $type"); header("X-Sendfile: $file"); # make sure $file is the full path, not relative exit();
mod_xsendfile nimmt den X-Sendfile-Header auf und sendet die Datei an den Browser selbst. Dies kann einen echten Leistungsunterschied bewirken, insbesondere bei großen Dateien. Die meisten der vorgeschlagenen Lösungen lesen die gesamte Datei in den Speicher und drucken sie dann aus. Das ist für eine 20-KByte-Bilddatei in Ordnung, aber wenn Sie eine 200-MByte-TIFF-Datei haben, treten Probleme auf.
quelle
$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; } }
http://php.net/manual/en/function.fpassthru.php
quelle
Versuche dies:
<?php header("Content-type: image/jpeg"); readfile("/path/to/image.jpg"); exit(0); ?>
quelle
header('Content-type: image/jpeg'); readfile($image);
quelle
Für den nächsten Mann oder die nächste Frau, die dieses Problem hat, hat Folgendes für mich funktioniert:
ob_start(); header('Content-Type: '.$mimetype); ob_end_clean(); $fp = fopen($fullyQualifiedFilepath, 'rb'); fpassthru($fp); exit;
Sie brauchen das alles und nur das. Wenn Ihr Mimetyp variiert, schauen Sie sich PHPs mime_content_type ($ filepath) an.
quelle
$file = '../image.jpg'; $type = 'image/jpeg'; header('Content-Type:'.$type); header('Content-Length: ' . filesize($file)); $img = file_get_contents($file); echo $img;
Das funktioniert bei mir! Ich habe es auf Code Igniter getestet. Wenn ich Readfile verwende, wird das Bild nicht angezeigt. Manchmal nur JPG anzeigen, manchmal nur große Datei. Aber nachdem ich es in "file_get_contents" geändert habe, bekomme ich den Geschmack und funktioniert !! Dies ist der Screenshoot: Screenshot des "sicheren Bildes" aus der Datenbank
quelle
(Erweiterung der akzeptierten Antwort ...)
Ich musste:
jpg
Bildes und ein animiertesgif
, und,Ich habe dies erreicht, indem ich eine "sekundäre"
.htaccess
Datei in dem Unterordner erstellt habe, in dem sich die Bilder befinden.Die Datei enthält nur eine Zeile:
Im selben Ordner habe ich die beiden 'Original'-Bilddateien (wir nennen sie
orig.jpg
undorig.gif
) sowie zwei Variationen des [vereinfachten] Skripts unten gespeichert (gespeichert alsmyimage.jpg
undmyimage.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); ?>
Die Bilder werden normal gerendert (oder animiert) und können auf eine der normalen Arten für Bilder (wie ein
<img>
Tag) aufgerufen werden. Sie speichern eine Aufzeichnung der besuchenden IP, während sie für den Benutzer unsichtbar sind.quelle
<?php header("Content-Type: $type"); readfile($file);
Das ist die Kurzversion. Es gibt ein paar zusätzliche kleine Dinge, die Sie tun können, um die Dinge schöner zu machen, aber das wird für Sie funktionieren.
quelle
Sie können den Header verwenden , um den richtigen Inhaltstyp zu senden:
header('Content-Type: ' . $type);
Und
readfile
um den Inhalt des Bildes auszugeben:readfile($file);
Und vielleicht (wahrscheinlich nicht notwendig, aber nur für den Fall) müssen Sie auch den Content-Length-Header senden:
header('Content-Length: ' . filesize($file));
Hinweis: Stellen Sie sicher, dass Sie nichts anderes als Ihre Bilddaten ausgeben (z. B. kein Leerraum) , da dies sonst kein gültiges Bild mehr ist.
quelle
Sie können
finfo
(PHP 5.3+) verwenden, um den richtigen MIME-Typ zu erhalten.$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 : Sie müssen nicht angeben
Content-Length
, Apache wird es für Sie tun.quelle
header("Content-type: image/png"); echo file_get_contents(".../image.png");
Der erste Schritt besteht darin, das Bild von einem bestimmten Ort abzurufen und es dann in einer Variablen zu speichern. Zu diesem Zweck verwenden wir die Funktion file_get_contents () mit dem Ziel als Parameter. Als nächstes legen wir den Inhaltstyp der Ausgabeseite mithilfe der Header-Datei als Bildtyp fest. Schließlich drucken wir die abgerufene Datei mit Echo.
quelle
Content-type: image/png
Ausgabe eines JPG-Bildes festgelegt? Warum sollte die gesamte Datei in eine Variable eingelesen werden? Sollte nichtreadfile
eine viel bessere Speicherleistung haben?