У меня есть веб-приложение с использованием PHP и PDO с подготовленными операторами SQLSRV для отображения ссылок на файлы для загрузки. Внутренний PHP-скрипт «download.php» проверяет различные элементы перед тем, как загружать PDF-файл пользователю. Затем файл download.php должен обновить несколько таблиц SQL и передать файл PDF пользователю.PHP скрипт загрузки PDF-файлов выполняется дважды
Просьба ознакомиться с моим Previous Question и, если вам нужна дополнительная информация, устранение неполадок завершено.
После устранения неполадок произошла ошибка, о которой я думал (и, следовательно, предыдущий вопрос, заданный мной) была неправильной. Сценарий загрузки выполняется несколько раз для каждой загрузки файла.
Я искал журналы сервера и во время отладки с Firebug я вижу, как скрипт download.php делает несколько запросов GET на сервер. Иногда скрипт завершается только один раз, как и ожидалось. В других случаях скрипт выполняет три-четыре запроса для одного щелчка ссылки для загрузки.
Теперь, когда я более полно понимаю, что происходит с ошибкой, мне нужно немного помочь в ее исправлении. Мне нужно, чтобы сценарий запускался несколько раз и, таким образом, обновлял таблицу SQL с записями, которые находятся в пределах нескольких миллисекунд друг от друга.
просмотра страниц проверяет базу данных SQL для файлов текущего пользователя разрешен доступ, и отображает список ссылок:
<a href='download.php?f={$item['name']}&t={$type}' target='_blank'>{$item['name']}</a>
Поскольку значения необходимы для сценария download.php работать, я не может изменить запрос на $ _POST вместо $ _GET.
То, что я пробовал:
Проверка/установка переменной сеанса для состояния «загрузка», перед
getfile()
который сбрасывает прямо передexit(0)
Положив операторы SQL в отдельном PHP файл и require'ing что
Добавление
sleep(1)
послеgetfile()
Комментирование информации заголовка/PDF
Первые три меры не работают, чтобы предотвратить двойное/тройное выполнение сценария PHP загрузки. Тем не менее, последняя мера предотвращает двойное/тройное выполнение PHP-скрипта, но, конечно, PDF никогда не доставляется в клиентский браузер!
Вопрос: Как я могу гарантировать, что только одна вставка/обновление PER DOWNLOAD ONE вставлена в базу данных или, по крайней мере, как я могу предотвратить выполнение сценария PHP несколько раз?
UPDATE
Скриншот выпуска в поджигатель:
один запрос:
Две просьбы:
download.php сценарий
<?php
session_start();
require("cgi-bin/auth.php");
// Don't timeout when downloading large files
@ignore_user_abort(1);
@set_time_limit(0);
//error_reporting(E_ALL);
//ini_set('display_errors',1);
function getfile() {
if (!isset($_GET['f']) || !isset($_GET['t'])) {
echo "Nothing to do!";
exit(0);
}
require('cgi-bin/connect_db_pdf.php');
//Update variables
$vuname = strtolower(trim($_SESSION['uname']));
$file = trim(basename($_GET['f'])); //Filename we're looking for
$type = trim($_GET['t']);//Filetype
if (!preg_match('/^[a-zA-Z0-9_\-\.]{1,60}$/', $file) || !preg_match('/^av|ds|cr|dp$/', $type)) {
header('Location: error.php');
exit(0);
}
try {
$sQuery = "SELECT TOP 1 * FROM pdf_info WHERE PDF_name=:sfile AND type=:stype";
$statm = $conn->prepare($sQuery);
$statm->execute(array(':sfile'=>$file,':stype'=>$type));
$result = $statm->fetchAll();
$count = count($result);
$sQuery = null;
$statm = null;
if ($count == 1){ //File was found in the database so let them download it. Update the time as well
$result = $result[0];
$sQuery = "INSERT INTO access (PDF_name,PDF_type,PDF_time,PDF_access) VALUES (:ac_file, :ac_type, GetDate(), :ac_vuname); UPDATE pdf_info SET last_view=GetDate(),viewed_uname=:vuname WHERE PDF_name=:file AND PDF_type=:type";
$statm = $conn->prepare($sQuery);
$statm->execute(array(':ac_vuname'=>$vuname, ':ac_file'=>$file, ':ac_type'=>$type,':vuname'=>$vuname, ':file'=>$file, ':type'=>$type));
$count = $statm->rowCount();
$sQuery = null;
$statm = null;
//$result is the first element from the SELECT query outside the 'if' scope.
$file_loc = $result['floc'];
$file_name = $result['PDF_name'];
// Commenting from this line to right after the exit(0) updates the database only ONCE, but then the PDF file is never sent to the browser!
header("Content-Type: application/pdf");
header("Pragma: no-cache");
header("Cache-Control: no-cache");
header("Content-Length: " . filesize($file_loc));
header("Accept-Ranges: bytes");
header("Content-Disposition: inline; filename={$file_name}");
ob_clean();
flush();
readfile($file_loc);
exit(0);
} else { //We did not find a file in the database. Redirect the user to the view page.
header("Location: view.php");
exit(0);
}
} catch(PDOException $err) {//PDO SQL error.
//echo $err;
header('Location: error.php');
exit(0);
}
}
getfile();
?>
Просто уточнить - вы не знаете, что * точно вызывает несколько загрузок, правильно? Я думаю, что стоит продолжать копаться, вместо того, чтобы пытаться исправить этот симптом. (Хотя я понятия не имею, что может вызвать это ...) –
@pekka Правильно; Я не знаю, что вызывает множественные казни, я просто знаю, что они происходят. Кроме того, сам файл не загружается несколько раз, что я могу сказать. Ссылка просмотра только когда-либо открывает одно окно, и один файл загружается за клик. – PenguinCoder
Хм. Если Firebug показывает несколько выстрелов «хитов», для них должна быть причина. Где именно происходят эти хиты? На что они похожи? Вы используете JavaScript на своей странице? Ссылка ссылки на скачивание в другом месте страницы? –