Я хочу загрузить 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 googling «Свой путь по умолчанию для журнала ошибок Apache Apache». Таким образом, если вы используете OS X, вы можете выполнить поиск «Путь по умолчанию для журнала ошибок Mac Apache».
Когда вы уверены, что ваш код работает нормально, предпочтительнее удалить (или прокомментировать) эту строку по соображениям безопасности и эстетики.
Другим важным союзником, особенно для новичков, является официальная документация PHP; копирование и вставка могут быть хорошими, но только если за ними следует тщательное чтение кода: нам нужно понять каждую команду! В вашем случае, если вы прочитали главу о header()
, вы поймете, что
header () должен быть вызван до отправки любого фактического вывода либо с помощью обычных тегов HTML, пустых строк в файле, либо из PHP. Очень распространенная ошибка для чтения кода с включением или требованием, функциями или другой функцией доступа к файлам, а также пробелы или пустые строки, которые выводятся перед вызовом 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 = 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 );
Также важно разместить die()
или exit
после readfile()
, иначе ваш скрипт выведет также следующий код 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 вы пишете как "<a href=\"download.php?id=\$id\"
: обратная косая черта ( \
) за строкой с двойными кавычками – это escape-символ, означающий« не интерпретировать- it, print-it ", поэтому знак доллара печатается как-it, а переменная не передается. Ваша эффективная ссылка: 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);
… и ваш скрипт сделан.
Если вы хотите получить доступ к файлу PDF с сервера, используя URL-адрес из базы данных, вы можете просмотреть функцию file_get_contents:
http://php.net/manual/en/function.file-get-contents.php
Вам нужно будет передать URL-адрес pdf в качестве параметра функции file_get_contents.
file_get_contents($file);