使用保存在数据库中的路径下载pdf文件? [英] Download a pdf file using path saved in database?

查看:81
本文介绍了使用保存在数据库中的路径下载pdf文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从一个文件夹下载PDF文件,但是当我尝试读取该文件时,出现错误无法加载PDF".当我尝试下载它时,会下载损坏的文件.

I want to download a PDF file from a folder but when I try to read the file it gives the error "failed to load PDF". When I try to download it, a corrupt file is downloaded.

这是我的代码:

<?php

    $con=mysqli_connect("localhost","root","");
    if(!isset($con)){
        echo "Database not connected";
    }
    $db=mysqli_select_db($con,"mahmood_faridi");
    $query=("SELECT * FROM books");
    $result=mysqli_query($con,$query);
    while(list($id,$file)=mysqli_fetch_array($result)){
        echo "<a href=\"download.php?id=\$id\">$file</a><br>";
    }

    if(isset($_GET['id'])){
        $id    = $_GET['id'];   
        $query = "SELECT  link FROM books WHERE id = '$id' limit=1";
        $result=mysqli_query($con,$query);
        $file=mysqli_fetch_object($result); 
        header('Content-type: application/pdf');
        header('Content-Disposition: inline');
        header('Content-Transfer-Encoding: binary');
        header('Accept-Ranges: bytes');

        @readfile($file);
    }
    mysqli_close($con);
?>

推荐答案

您的脚本中有很多错误.

In your script there are many errors.

首先,当我们编写一个php脚本时,激活错误报告是一种很好的做法.这不是随心所欲:显示错误是我们在代码调试中的第一个盟友.要激活错误报告,请将这两行放在脚本顶部:

When we write a php script, first of all, it's good practice activate error reporting; this is not a caprice: showing errors is our first allied in code debugging. To activate error reporting, put this two line at top of your script:

error_reporting( E_ALL );
ini_set( "display_errors", 1 );

这不能完全解决错误报告,因为省略了编译错误(例如,如果您编写的是eco而不是echo),则只会看到空白页.发生这种情况时,要检查代码在哪里失败,您必须读取Apache日志文件.您可以在Google日志文件的Google搜索中找到您的操作系统Apache错误日志默认路径"的位置.因此,如果使用OS X,则可以搜索"Mac Apache错误日志默认路径".

This not resolve completely error reporting, because compile errors (like if you write eco instead of echo) are omitted, and you will see only a blank page. When this occur, to check where your code fails, you have to read the Apache logfile. You can find the location of Apache logfile googling "Your OS Apache error log default path". So, if you use OS X, you can search "Mac Apache error log default path".

出于安全和美观的原因,当您确定自己的代码可以正常工作时,最好删除(或注释)这些行.

When you are sure that your code works fine, is preferable to remove (or comment) these line, for security and esthetic reasons.

PHP官方文档是另一个重要的盟友,尤其对于新手而言.复制粘贴可以很好,但是只有在仔细阅读代码之后:我们需要了解每个命令!就您而言,如果您已阅读有关 header() 的章节,明白

Another important ally, especially for a newbie, is the PHP Official documentation; copy-and-paste can be good, but only if followed by a careful reading of the code: we need to understand every command! In your case, if you had read the chapter about header(), you would understand that

在发送任何实际输出之前,必须通过普通的HTML标记,文件中的空白行或从PHP发送

header().读取包含,或要求函数或另一个文件访问函数的代码,并在调用header()之前输出空格或空行,这是一个非常常见的错误.

header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP. It is a very common error to read code with include, or require, functions, or another file access function, and have spaces or empty lines that are output before header() is called.

这是您的第一个大错误:首先显示可用文件列表,然后调用header()函数,该操作失败.如果您已激活错误报告功能,则将报告错误.

This is your first big error: you first display the list of available files, then call header() function, that fails. If you had activate error reporting, the mistake it would have been reported.

因此,您的代码必须以这种方式继续:

So, your code must continue in this way:

if( !isset($con) ) die( "Database not connected" );
$db = mysqli_select_db( $con, "mahmood_faridi" ) or die( "Unable to select Database" );

if( isset( $_GET['id'] ) )
{
    $id    = $_GET['id'];
    $query = "SELECT link FROM books WHERE id = '$id' LIMIT 1";

然后,检查结果.在我们的原始代码中,您编写WHERE id = '$id' limit=1.如果您检查了结果,则将收到以下消息:

Then, check the result. In our original code, you write WHERE id = '$id' limit=1. If you had checked the result, you would have got this message:

查询错误:您的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册以获取正确的语法,以在第1行的"= 1"附近使用

Query error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '=1' at line 1

,您将意识到查询中出了点问题.

and you would have realized that something was wrong in the query.

    $result = mysqli_query( $con, $query ) or die( "Query error: " . mysqli_error( $con ) ); 
    if( !mysqli_num_rows( $result ) ) die( "ID $id Not Found" );

    $file   = mysqli_fetch_object( $result );

然后,检查文件是否存在.在原始代码中,您编写了readfile( $file ),但是$file是一个对象($file = mysqli_fetch_object( $result )),而不是文件路径.文件路径实际上是$file->link.

Then, check if the file exists. In your original code, you write readfile( $file ), but $file is an object ($file = mysqli_fetch_object( $result )), not a filepath. The filepath is actually $file->link.

如果您已检查文件是否存在并激活了错误报告,则将收到以下消息:

If you had checked if the file exists and activated error reporting, you would have got these messages:

警告:file_exists()期望参数1为有效路径,在XX行的/your/script/path.php中给出的对象
找不到文件

Warning: file_exists() expects parameter 1 to be a valid path, object given in /your/script/path.php on line XX
File Not Found

,您将得到错误类型和要检查的行.

and you would have the kind of error and the line to check.

    if( ! file_exists( $file->link ) ) die( "File Not Found" );

    header( 'Content-type: application/pdf' );
    header( 'Content-Disposition: inline' );
    header( 'Content-Transfer-Encoding: binary' );
    header( 'Accept-Ranges: bytes' );

    @readfile( $file->link );

同样重要的是,在readfile()之后放置die()exit,否则您的脚本也会输出以下html代码,并且您的pdf文件将损坏:

Also important, place a die() or exit after readfile(), otherwise your script will output also following html code, and your pdf file will result corrupt:

    die();
}

现在,您可以放置​​代码以显示文件列表(仅当未发送pdf文件时才会执行);同样在这种情况下,最好一步一步检查结果:

Now, you can place the code to display your files list (that will be executed only if pdf file is not sended); also in this case, it is good to check the result step-by-step:

$query = "SELECT * FROM books";     // <-- brackets are superfluous, but are not error
if( ! $result = mysqli_query( $con, $query ) ) die( "Query error: " . mysqli_error( $con ) );

if( !mysqli_num_rows( $result ) ) die( "Database empty" );

在原始的while循环中,您将其写为url "<a href=\"download.php?id=\$id\":双引号字符串后面的反斜杠(\)是字符转义符,表示不解释,不打印",因此美元符号按原样打印,并且不传递变量.您的有效链接是' http://example.com/download.php?id= $ id"而不是" http://example.com/download.php?id=1".提防小事情.

In your original while loop, you write as url "<a href=\"download.php?id=\$id\": the backslash (\) behind a double-quoted string is a character escape that means "not interpret-it, print-it", so the dollar sign is printed as-it and the variable is not passsed. Your effective link is 'http://example.com/download.php?id=$id' instead of 'http://example.com/download.php?id=1'. Watch out for the little things.

while( list( $id, $file ) = mysqli_fetch_array( $result ) )
{
    echo "<a href=\"download.php?id=$id\">$file</a><br>";
}

mysqli_close($con);

...并且您的脚本已完成.

... and your script is done.

这篇关于使用保存在数据库中的路径下载pdf文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆