it-swarm.com.de

Herunterladen von Dateien mit erzwingen PHP

Ich habe eine CSV-Datei auf meinem Server. Wenn ein Benutzer auf einen Link klickt, sollte er ihn herunterladen, er öffnet sich jedoch in meinem Browserfenster.

Mein Code sieht wie folgt aus

<a href="files/csv/example/example.csv">
    Click here to download an example of the "CSV" file
</a>

Es ist ein normaler Webserver, auf dem ich meine gesamte Entwicklungsarbeit erledige.

Ich habe so etwas ausprobiert:

<a href="files/csv/example/csv.php">
    Click here to download an example of the "CSV" file
</a>

Nun der Inhalt meiner csv.php-Datei:

header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');

Jetzt ist mein Problem das Herunterladen, aber nicht meine CSV-Datei. Es erstellt eine neue Datei.

61
Roland

.htaccess-Lösung

Fügen Sie Ihrer .htaccess-Datei Folgendes hinzu, um alle CSV-Dateien auf Ihrem Server brutal zum Herunterladen zu zwingen:

AddType application/octet-stream csv

PHP-Lösung

header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');
readfile("/path/to/yourfile.csv");
101
robjmills

Oder Sie können dies mit HTML5 tun. Einfach mit 

<a href="example.csv" download>download not open it</a>
21
AtanuCSE

Dies kann nicht zuverlässig durchgeführt werden, da der Browser entscheiden muss, was er mit einer URL tun soll, die er abrufen soll.

Sie können vorschlagen an den Browser, den er anbieten soll, umgehend auf Festplatte zu speichern, indem Sie einen Content-Disposition-Header senden:

header("Content-disposition: attachment");

Ich bin mir nicht sicher, wie gut dies von verschiedenen Browsern unterstützt wird. Die Alternative ist, einen Content-Typ von Anwendung/Octet-Stream zu senden, aber das ist ein Hack (im Grunde sagen Sie dem Browser "Ich verrate Ihnen nicht, um welche Art von Datei es sich handelt") und hängt von den meisten ab Browser bieten dann einen Download-Dialog an) und verursachen angeblich Probleme mit dem Internet Explorer.

Lesen Sie mehr dazu in den Web Authoring-FAQs.

Edit Sie haben bereits zu einer PHP -Datei gewechselt, um die Daten zu liefern. Dies ist erforderlich, um den Content-Dispositions-Header festzulegen (sofern nicht einige arkane Apache-Einstellungen vorhanden sind, die dies ebenfalls können). Jetzt müssen Sie nur noch die PHP -Datei lesen, um den Inhalt der CSV-Datei zu lesen und auszudrucken. Der filename=example.csv im Header gibt dem Clientbrowser nur den Namen der Datei an, der für die Datei zu verwenden ist Holen Sie die Daten aus der Datei auf dem Server.

15

Hier ist eine Browser-sicherere Lösung:

    $fp = @fopen($yourfile, 'rb');

    if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
{
    header('Content-Type: "application/octet-stream"');
    header('Content-Disposition: attachment; filename="yourname.file"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header("Content-Transfer-Encoding: binary");
    header('Pragma: public');
    header("Content-Length: ".filesize($yourfile));
}
else
{
    header('Content-Type: "application/octet-stream"');
    header('Content-Disposition: attachment; filename="yourname.file"');
    header("Content-Transfer-Encoding: binary");
    header('Expires: 0');
    header('Pragma: no-cache');
    header("Content-Length: ".filesize($yourfile));
}

fpassthru($fp);
fclose($fp);
12
Franz

Konfigurieren Sie Ihren Server, um die Datei mit dem Medientyp application/octet-stream zu senden.

7
Gumbo

Schöne saubere Lösung:

<?php
    header('Content-Type: application/download');
    header('Content-Disposition: attachment; filename="example.csv"');
    header("Content-Length: " . filesize("example.csv"));

    $fp = fopen("example.csv", "r");
    fpassthru($fp);
    fclose($fp);
?>
2
vdbuilder

Das bedeutet, dass Ihr Browser diesen Dateityp verarbeiten kann.

Wenn Sie es nicht mögen, bieten Sie am einfachsten Zip-Dateien an. Jeder kann Zip-Dateien verarbeiten und ist standardmäßig herunterladbar.

2
StampedeXV

Eine vorherige Antwort auf dieser Seite beschreibt, wie Sie mit .htaccess das Herunterladen aller Dateien eines bestimmten Typs erzwingen. Die Lösung funktioniert jedoch nicht mit allen Dateitypen in allen Browsern. Dies ist ein zuverlässiger Weg:

<FilesMatch "\.(?i:csv)$">
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</FilesMatch>

Möglicherweise müssen Sie den Cache Ihres Browsers leeren, damit dies ordnungsgemäß funktioniert.

1
Chris Harrison

Wenn Sie es mit Ihrer Anwendung selbst machen ... Ich hoffe, dieser Code hilft.

HTML

In href - Sie müssen download_file.php zusammen mit Ihrer URL hinzufügen:

<a class="download" href="'/download_file.php?fileSource='+http://www.google.com/logo_small.png" target="_blank" title="YourTitle">

PHP

/* Here is the Download.php file to force download stuff */

<?php
    $fullPath = $_GET['fileSource'];
    if($fullPath) {
        $fsize = filesize($fullPath);
        $path_parts = pathinfo($fullPath);
        $ext = strtolower($path_parts["extension"]);

        switch ($ext) {
            case "pdf":
                header("Content-Disposition: attachment; filename=\"" . $path_parts["basename"]."\""); // Use 'attachment' to force a download
                header("Content-type: application/pdf"); // Add here more headers for diff. extensions
                break;

            default;
                header("Content-type: application/octet-stream");
                header("Content-Disposition: filename=\"" . $path_parts["basename"]."\"");
        }

        if($fsize) { // Checking if file size exist
            header("Content-length: $fsize");
        }
        readfile($fullPath);
        exit;
    }
?>
0
hussain

Um das Herunterladen zu erzwingen, können Sie den Content-Type: application/force-download-Header verwenden, der von den meisten Browsern unterstützt wird:

function downloadFile($filePath)
{
    header('Content-Type: application/force-download');
    header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
    header('Content-Length: ' . filesize($filePath));
    readfile($filePath);
}

EIN BESSERER WEG

Das Herunterladen von Dateien auf diese Weise ist insbesondere für große Dateien nicht die beste Idee. PHP erfordert zusätzliche CPU/Speicher zum Lesen und Ausgeben von Dateiinhalten. Beim Umgang mit großen Dateien können Zeit-/Speichergrenzen erreicht werden.

Eine bessere Methode wäre die Verwendung von PHP zum Authentifizieren und Gewähren des Zugriffs auf eine Datei. Die eigentliche Dateiservierung sollte mithilfe der X-SENDFILE-Methode an einen Webserver delegiert werden (dies erfordert einige Webserverkonfigurationen):

Nachdem Sie den Webserver für die Verarbeitung von X-SENDFILE konfiguriert haben, müssen Sie einfach readfile($filePath) durch header('X-SENDFILE: ' . $filePath) ersetzen. Der Webserver kümmert sich dann um die Dateiservierung. Dies erfordert weniger Ressourcen als die Verwendung von PHP readfile.

(Für Nginx verwenden Sie X-Accel-Redirect-Header anstelle von X-SENDFILE)

Hinweis: Wenn Sie leere Dateien herunterladen, bedeutet dies, dass Sie Ihren Webserver nicht für die Verarbeitung von X-SENDFILE-Header konfiguriert haben. Überprüfen Sie die Links oben, um zu sehen, wie Sie Ihren Webserver richtig konfigurieren.

0
Dima L.