Forcing om een ​​bestand te downloaden met PHP

Ik heb een CSV-bestand op mijn server. Als een gebruiker op een link klikt, moet deze downloaden, maar in plaats daarvan opent het in mijn browservenster.

Mijn code ziet er als volgt uit

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

Het is een normale webserver waar ik al mijn ontwikkeling aan heb.

Ik heb zoiets geprobeerd:

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

Nu de inhoud van mijn csv.phpbestand:

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

Nu mijn probleem is het downloaden, maar niet mijn CSV-bestand. Het maakt een nieuw bestand.


Antwoord 1, Autoriteit 100%

.Htaccess-oplossing

Naar brute forceer alle CSV-bestanden op uw server om te downloaden, voegt u uw .htaccess-bestand toe:

AddType application/octet-stream csv

PHP-oplossing

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

Antwoord 2, Autoriteit 25%

of u kunt dit doen met HTML5. Gewoon met

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

Antwoord 3, Autoriteit 15%

Dit kan niet betrouwbaar worden gedaan, omdat het aan de browser is om te beslissen wat te doen met een URL is gevraagd om op te halen.

U kunt voorstellen aan de browser die het moet aanbieden om meteen te “opslaan naar schijf” door een header voor content-dispositie te verzenden:

header("Content-disposition: attachment");

Ik weet niet zeker hoe goed dit wordt ondersteund door verschillende browsers. Het alternatief is om een ​​content-type applicatie / octet-stream te verzenden, maar dat is een hack (je vertelt in feite de browser “Ik vertel je niet wat voor soort bestand is” en afhankelijk van het feit dat het meest is Browsers bieden dan een downloaddialoog) en veroorzaakt naar verluidt problemen met Internet Explorer.

Lees hierover meer informatie in de Web Authoring FAQ.

Bewerken U bent al overgeschakeld naar een PHP-bestand om de gegevens te bezorgen – die nodig is om de header van de inhoud-dispositie in te stellen (tenzij er enkele arcane Apache-instellingen zijn die dit ook kunnen doen). Nu is alles wat er nog over is, is voor dat PHP-bestand om de inhoud van het CSV-bestand te lezen en ze af te drukken – de filename=example.csvin de koptekst suggereert alleen aan de clientbrowser welke naam voor gebruik Het bestand, het haalt de gegevens uit het bestand op de server niet echt op.


Antwoord 4, Autoriteit 11%

Hier is een meer browser-safe-oplossing:

   $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);

Antwoord 5, autoriteit 7%

Configureer uw server om het bestand te verzenden met het mediatype application/octet-stream.


Antwoord 6, autoriteit 2%

Een eerder antwoord op deze pagina beschrijft hoe je .htaccess gebruikt om alle bestanden van een bepaald type te forceren om te downloaden. De oplossing werkt echter niet met alle bestandstypen in alle browsers. Dit is een betrouwbaardere manier:

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

Mogelijk moet u uw browsercache leegmaken om te zien of dit correct werkt.


Antwoord 7, autoriteit 2%

Dit betekent dat uw browser dit bestandstype aankan.

Als je het niet leuk vindt, is de eenvoudigste methode om ZIP-bestanden aan te bieden. Iedereen kan ZIP-bestanden aan en ze kunnen standaard worden gedownload.


Antwoord 8, autoriteit 2%

Mooie schone oplossing:

<?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);
?>

Antwoord 9

Als je het met je applicatie zelf doet… Ik hoop dat deze code helpt.

HTML

In href — je moet download_file.php samen met je URL toevoegen:

<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;
    }
?>

Antwoord 10

Om het downloaden te forceren, kunt u de header Content-Type: application/force-downloadgebruiken, die door de meeste browsers wordt ondersteund:

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

EEN BETERE MANIER

Het op deze manier downloaden van bestanden is niet het beste idee, vooral niet voor grote bestanden. PHP heeft extra CPU / geheugen nodig om de inhoud van bestanden te lezen en uit te voeren en bij het omgaan met grote bestanden kunnen tijd- / geheugenlimieten oplopen.

Een betere manier zou zijn om PHP te gebruiken om een ​​bestand te authenticeren en toegang te verlenen, en de daadwerkelijke bestandsserving moet worden gedelegeerd aan een webserver met behulp van de X-SENDFILE-methode (vereist enige webserverconfiguratie):

Na het configureren van de webserver om X-SENDFILEte verwerken, vervangt u gewoon readfile($filePath)door header('X-SENDFILE: ' . $filePath)en webserver zorgen voor bestandsserving, wat minder resources vereist dan het gebruik van PHP readfile.

(Gebruik voor Nginx de kop X-Accel-Redirectin plaats van X-SENDFILE)

Opmerking: als je uiteindelijk lege bestanden downloadt, betekent dit dat je je webserver niet hebt geconfigureerd om de X-SENDFILE-header te verwerken. Controleer de bovenstaande links om te zien hoe u uw webserver correct kunt configureren.

Other episodes