我想从文件夹中下载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);
?>
在您的脚本中有许多错误。
当我们编写一个php脚本时,首先,激活错误报告是一个很好的做法;这不是随心所欲的:显示错误是我们在代码调试中的第一个联盟。要激活错误报告,请将以下两行放在脚本顶部:
error_reporting( E_ALL );
ini_set( "display_errors", 1 );
这并不能完全解决错误报告,因为省略了编译错误(例如,如果您编写eco
而不是echo
(,并且您只会看到一个空白页。发生这种情况时,要检查代码失败的位置,您必须读取 Apache 日志文件。您可以在谷歌搜索"您的操作系统Apache错误日志默认路径"中找到Apache日志文件的位置。因此,如果您使用OS X,则可以搜索" Mac Apache错误日志默认路径"。
当您确定您的代码工作正常时,出于安全和美观的原因,最好删除(或注释(这些行。
另一个重要的盟友,特别是对于新手来说,是 PHP 官方文档;复制和粘贴可以很好,但前提是仔细阅读代码:我们需要理解每个命令!就您而言,如果您阅读了有关header()
的章节,您就会明白
header(( 必须在发送任何实际输出之前调用,无论是通过普通 HTML 标记、文件中的空行还是从 PHP 发送。读取包含或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 服务器版本对应的手册,了解在第 1 行"=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 是有效的路径,对象在/your/script/path.php 第 XX
行 找不到文件
您将有要检查的错误类型和行。
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 文件将导致损坏:
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'"
:双引号字符串后面的反斜杠 ('
( 是一个字符转义,表示"不解释它,打印它",所以美元符号按原样打印,变量不传递。您的有效链接是"http://example.com/download.php?id=$id"而不是"http://example.com/download.php?id=1"。注意小事。
while( list( $id, $file ) = mysqli_fetch_array( $result ) )
{
echo "<a href='"download.php?id=$id'">$file</a><br>";
}
mysqli_close($con);
。你的脚本就完成了。
如果您正在寻找使用数据库中的 url 从服务器访问 pdf 文件,您可能需要查看 file_get_contents 函数:
http://php.net/manual/en/function.file-get-contents.php
您需要将 pdf 的 url 作为参数传递给 file_get_contents 函数。
file_get_contents($file);