使用保存在数据库中的路径下载pdf文件?

时间:2016-02-05 23:05:05

标签: php pdf

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

这是我的代码:

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

2 个答案:

答案 0 :(得分:1)

在你的脚本中有很多错误。

当我们编写php脚本时,首先,它的好习惯是激活错误报告;这不是一个任性:显示错误是我们在代码调试中的第一个联盟。要激活错误报告,请将这两行放在脚本的顶部:

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

这不能完全解决错误报告,因为编译错误(如果您编写eco而不是echo)将被省略,并且您将只看到空白页面。发生这种情况时,要检查代码失败的位置,您必须阅读Apache日志文件。您可以找到Apache日志文件的位置google搜索“您的操作系统Apache错误日志默认路径”。因此,如果您使用OS X,则可以搜索&#34; Mac Apache错误日志默认路径&#34;。

当您确定您的代码正常工作时,出于安全和美观的原因,最好删除(或评论)这些代码。

另一个重要的盟友,特别是新手,是PHP官方文档;复制粘贴可以很好,但只有在仔细阅读代码之后:我们需要了解每个命令!在您的情况下,如果您已阅读有关header()的章节,您就会理解

  必须在发送任何实际输出之前调用

header(),无论是普通HTML标记,文件中的空行还是PHP。使用include或require,函数或其他文件访问函数读取代码是一个非常常见的错误,并且在调用header()之前输出空格或空行。

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

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

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。如果您检查了结果,则会收到以下消息:

  

查询错误:您的SQL语法中有错误;检查与您的MySQL服务器版本对应的手册,以便在&#39; = 1&#39;附近使用正确的语法。在第1行

你会意识到查询中出了问题。

    $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

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

  

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

你会有这种错误和要检查的行。

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

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

    die();
}

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

$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\":双引号字符串后面的反斜杠(\)是一个字符转义符,意思是“不解释它, print-it“,所以美元符号按原样打印,变量未传递。您的有效链接是&#39; http://example.com/download.php?id= $ id&#39;而不是&#39; http://example.com/download.php?id=1&#39;。小心一点。

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

mysqli_close($con);

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

答案 1 :(得分:0)

如果您正在尝试使用数据库中的URL从服务器访问pdf文件,您可能需要查看file_get_contents函数:

http://php.net/manual/en/function.file-get-contents.php

您需要将pdf的url作为参数传递给file_get_contents函数。

file_get_contents($file);