Cara download file pdf dengan php

In this tutorial you will learn how to force download a file using PHP.

Downloading Files with PHP

Normally, you don't necessarily need to use any server side scripting language like PHP to download images, zip files, pdf documents, exe files, etc. If such kind of file is stored in a public accessible folder, you can just create a hyperlink pointing to that file, and whenever a user click on the link, browser will automatically downloads that file.

<a href="downloads/test.zip">Download Zip file</a>
<a href="downloads/masters.pdf">Download PDF file</a>
<a href="downloads/sample.jpg">Download Image file</a>
<a href="downloads/setup.exe">Download EXE file</a>

Clicking a link that points to a PDF or an Image file will not cause it to download to your hard drive directly. It will only open the file in your browser. Further you can save it to your hard drive. However, zip and exe files are downloaded automatically to the hard drive by default.


Forcing a Download Using PHP

You can force images or other kind of files to download directly to the user's hard drive using the PHP readfile() function. Here we're going to create a simple image gallery that allows users to download the image files from the browser with a single mouse click.

Let's create a file named "image-gallery.php" and place the following code inside it.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple Image Gallery</title>
<style type="text/css">
    .img-box{
        display: inline-block;
        text-align: center;
        margin: 0 15px;
    }
</style>
</head>
<body>
    <?php
    // Array containing sample image file names
    $images = array("kites.jpg", "balloons.jpg");
    
    // Loop through array to create image gallery
    foreach($images as $image){
        echo '<div class="img-box">';
            echo '<img src="images/' . $image . '" width="200" alt="' .  pathinfo($image, PATHINFO_FILENAME) .'">';
            echo '<p><a href="download.php?file=' . urlencode($image) . '">Download</a></p>';
        echo '</div>';
    }
    ?>
</body>
</html>

If you see the above example code carefully, you'll find the download link pints to a "download.php" file, the URL also contains image file name as a query string. Also, we've used PHP urlencode() function to encode the image file names so that it can be safely passed as URL parameter, because file names may contain URL unsafe characters.

Here's the complete code of "download.php" file, which force image download.

<?php
if(isset($_REQUEST["file"])){
    // Get parameters
    $file = urldecode($_REQUEST["file"]); // Decode URL-encoded string

    /* Test whether the file name contains illegal characters
    such as "../" using the regular expression */
    if(preg_match('/^[^.][-a-z0-9_.]+[a-z]$/i', $file)){
        $filepath = "images/" . $file;

        // Process download
        if(file_exists($filepath)) {
            header('Content-Description: File Transfer');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
            header('Expires: 0');
            header('Cache-Control: must-revalidate');
            header('Pragma: public');
            header('Content-Length: ' . filesize($filepath));
            flush(); // Flush system output buffer
            readfile($filepath);
            die();
        } else {
            http_response_code(404);
	        die();
        }
    } else {
        die("Invalid file name!");
    }
}
?>

Similarly, you can force download other files formats like word doc, pdf files, etc.

The regular expression in the above example (line no-8) will simply not allow those files whose name starts or ends with a dot character (.), for example, it allows the file names such as kites.jpg or Kites.jpg, myscript.min.js but do not allow kites.jpg. or .kites.jpg.

Please check out the tutorial on regular expressions to learn the regular expressions in details.

Saya memberikan tautan file pdf di halaman web saya untuk diunduh, seperti di bawah ini

<a href="myfile.pdf">Download Brochure</a>

Masalahnya adalah ketika pengguna mengklik tautan ini

  • Jika pengguna telah menginstal Adobe Acrobat, maka itu membuka file di jendela browser yang sama di Adobe Reader.
  • Jika Adobe Acrobat tidak diinstal maka akan muncul pop-up kepada pengguna untuk Mengunduh file.

Tapi saya ingin selalu muncul untuk pengguna untuk diunduh, terlepas dari "Adobe acrobat" diinstal atau tidak.

Tolong beritahu saya bagaimana saya bisa melakukan ini?

Alih-alih menautkan ke file .PDF, lakukan sesuatu seperti 

<a href="pdf_server.php?file=pdffilename">Download my eBook</a>

yang menghasilkan header khusus, membuka PDF (binary safe) dan mencetak data ke browser pengguna, lalu mereka dapat memilih untuk menyimpan PDF meskipun pengaturan browser mereka. Pdf_server.php akan terlihat seperti ini:

header("Content-Type: application/octet-stream");

$file = $_GET["file"] .".pdf";
header("Content-Disposition: attachment; filename=" . urlencode($file));   
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");            
header("Content-Length: " . filesize($file));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp))
{
    echo fread($fp, 65536);
    flush(); // this is essential for large downloads
} 
fclose($fp); 

PS: dan jelas menjalankan beberapa pemeriksaan kewarasan pada variabel "file" untuk mencegah orang mencuri file Anda seperti tidak menerima ekstensi file, menolak garis miring, tambahkan .pdf ke nilai

Ini adalah masalah umum tetapi hanya sedikit orang yang tahu ada solusi HTML 5 sederhana:

<a href="./directory/yourfile.pdf" download="newfilename">Download the pdf</a>

Di mana newfilename adalah nama file yang disarankan bagi pengguna untuk menyimpan file. Atau itu akan default ke nama file di sisi server jika Anda membiarkannya kosong, seperti ini:

<a href="./directory/yourfile.pdf" download>Download the pdf</a>

Kompatibilitas: Saya menguji ini pada Firefox 21 dan Iron, keduanya bekerja dengan baik. Ini mungkin tidak berfungsi pada browser HTML5-tidak kompatibel atau usang. Satu-satunya browser yang saya uji yang tidak memaksa unduhan adalah IE ...

Periksa kompatibilitas di sini: http://caniuse.com/#feat=download

Jangan loop melalui setiap baris file . Sebaliknya, gunakan readfile, ini lebih cepat. Ini dari situs php: http://php.net/manual/en/function.readfile.php

$file = $_GET["file"];
if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header("Content-Type: application/force-download");
    header('Content-Disposition: attachment; filename=' . urlencode(basename($file)));
    // header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit;
}

Pastikan untuk membersihkan variabel get Anda karena seseorang dapat mengunduh beberapa file php ...

Alih-alih menggunakan skrip PHP, untuk membaca dan membersihkan file, lebih rapi menulis ulang header menggunakan .htaccess Ini akan menyimpan URL "Bagus" (myfile.pdf bukannya download.php?myfile).

<FilesMatch "\.pdf$">
ForceType applicaton/octet-stream
Header set Content-Disposition attachment
</FilesMatch>

Saya menemukan cara untuk melakukannya dengan HTML lama biasa dan JavaScript/jQuery yang menurun dengan anggun. Diuji dalam IE7-10, Safari, Chrome, dan FF:

Tautan HTML untuk unduhan:

<p>Thanks for downloading! If your download doesn't start shortly, 
<a id="downloadLink" href="...yourpdf.pdf" target="_blank" 
type="application/octet-stream" download="yourpdf.pdf">click here</a>.</p>

jQuery (kode JavaScript murni akan lebih verbose) yang mensimulasikan mengklik tautan setelah jeda kecil:

var delay = 3000;
window.setTimeout(function(){$('#downloadLink')[0].click();},delay);

Untuk membuat ini lebih kuat, Anda dapat menambahkan deteksi fitur HTML5 dan jika tidak ada di sana maka gunakan window.open() untuk membuka jendela baru dengan file.

Ada cara yang lebih mudah di HTML5: Tambahkan atribut Download

Ini didukung oleh sebagian besar browser modern.

<a download href="file.pdf">Download PDF</a> 

Ini kuncinya:

header("Content-Type: application/octet-stream");

Aplikasi tipe-konten/x-pdf-dokumen atau aplikasi/pdf dikirim saat mengirim file PDF. Adobe Reader biasanya menetapkan handler untuk tipe MIME ini sehingga browser akan meneruskan dokumen ke Adobe Reader ketika salah satu dari PDF jenis MIME diterima.

Saya tahu saya sangat terlambat untuk menjawab ini tetapi saya menemukan peretasan untuk melakukan ini dalam javascript.

function downloadFile(src){
    var link=document.createElement('a');
    document.body.appendChild(link);
    link.href= src;
    link.download = '';
    link.click();
}

Coba ini:

<a href="pdf_server_with_path.php?file=pdffilename&path=http://myurl.com/mypath/">Download my eBook</a>

Kode di dalam pdf_server_with_path.php adalah:

header("Content-Type: application/octet-stream");

$file = $_GET["file"] .".pdf";
$path = $_GET["path"];
$fullfile = $path.$file;

header("Content-Disposition: attachment; filename=" . Urlencode($file));   
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");            
header("Content-Length: " . Filesize($fullfile));
flush(); // this doesn't really matter.
$fp = fopen($fullfile, "r");
while (!feof($fp))
{
    echo fread($fp, 65536);
    flush(); // this is essential for large downloads
} 
fclose($fp);

jika Anda perlu membatasi kecepatan unduh, gunakan kode ini !!

<?php
$local_file = 'file.Zip';
$download_file = 'name.Zip';

// set the download rate limit (=> 20,5 kb/s)
$download_rate = 20.5;
if(file_exists($local_file) && is_file($local_file))
{
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($local_file));
header('Content-Disposition: filename='.$download_file);

flush();
$file = fopen($local_file, "r");
while(!feof($file))
{
    // send the current file part to the browser
    print fread($file, round($download_rate * 1024));
    // flush the content to the browser
    flush();
    // sleep one second
    sleep(1);
}
fclose($file);}
else {
die('Error: The file '.$local_file.' does not exist!');
}

?>

Untuk informasi lebih lanjut klik di sini

Saya memecahkan masalah saya menggunakan seluruh url file PDF (Alih-alih hanya menempatkan nama file atau lokasi ke href): a href = "domain. com/pdf/filename.pdf" 

<!DOCTYPE html>  
<html xmlns="http://www.w3.org/1999/xhtml">  
<head>  
    <title>File Uploader</title>  
    <script src="../Script/angular1.3.8.js"></script>  
    <script src="../Script/angular-route.js"></script>  
    <script src="../UserScript/MyApp.js"></script>  
    <script src="../UserScript/FileUploder.js"></script>  
    <>  
        .percent {  
            position: absolute;  
            width: 300px;  
            height: 14px;  
            z-index: 1;  
            text-align: center;  
            font-size: 0.8em;  
            color: white;  
        }  

        .progress-bar {  
            width: 300px;  
            height: 14px;  
            border-radius: 10px;  
            border: 1px solid #CCC;  
            background-image: -webkit-gradient(linear, left top, left bottom, from(#6666cc), to(#4b4b95));  
            border-image: initial;  
        }  

        .uploaded {  
            padding: 0;  
            height: 14px;  
            border-radius: 10px;  
            background-image: -webkit-gradient(linear, left top, left bottom, from(#66cc00), to(#4b9500));  
            border-image: initial;  
        }  
    </>  
</head>  
<body ng-app="MyApp" ng-controller="FileUploder">  
    <div>  
        <table ="width:100%;border:solid;">  
            <tr>  
                <td>Select File</td>  
                <td>  
                    <input type="file" ng-model-instant id="fileToUpload" onchange="angular.element(this).scope().setFiles(this)" />  
                </td>  
            </tr>  
            <tr>  
                <td>File Size</td>  
                <td>  
                    <div ng-repeat="file in files.slice(0)">  
                        <span ng-switch="file.size > 1024*1024">  
                            <span ng-switch-when="true">{{file.size / 1024 / 1024 | number:2}} MB</span>  
                            <span ng-switch-default>{{file.size / 1024 | number:2}} kB</span>  
                        </span>  
                    </div>  
                </td>  
            </tr>             
            <tr>  
                <td>  
                    File Attach Status  
                </td>  
                <td>{{AttachStatus}}</td>  
            </tr>  
            <tr>  
                <td>  
                    <input type="button" value="Upload" ng-click="fnUpload();" />  
                </td>  
                <td>  
                    <input type="button" value="DownLoad" ng-click="fnDownLoad();" />  
                </td>  
            </tr>  
        </table>  
    </div>  
</body>  
</html>   

Ini pendekatan yang berbeda. Saya lebih suka daripada mengandalkan dukungan browser, atau alamat ini di lapisan aplikasi, untuk menggunakan logika server web.

Jika Anda menggunakan Apache, dan dapat meletakkan file .htaccess di direktori yang relevan, Anda dapat menggunakan kode di bawah ini. Tentu saja, Anda bisa meletakkan ini di httpd.conf juga, jika Anda memiliki akses ke sana.

<FilesMatch "\.(?i:pdf)$">
  Header set Content-Disposition attachment
</FilesMatch>

Arahan FilesMatch hanya sebuah regex sehingga bisa diatur secara terperinci seperti yang Anda inginkan, atau Anda bisa menambahkan ekstensi lain.

Baris Header melakukan hal yang sama dengan baris pertama dalam skrip PHP di atas. Jika Anda perlu mengatur baris Tipe Konten juga, Anda bisa melakukannya dengan cara yang sama, tetapi saya belum menganggapnya perlu.