脚本宝典收集整理的这篇文章主要介绍了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.
我尝试过的:
>在退出(0)之前取消设置的getfile()之前检查/设置会话变量的“下载”状态
>将sql语句放在一个单独的PHP文件中并要求它
>在getfile()之后添加sleep(1)
>评论标题/ PDF信息
前三个措施无法阻止PHP下载脚本的双/三次执行.但是,最后一项措施是否会阻止PHP脚本的双重/三重执行,但当然PDF永远不会传送到客户端浏览器!
问题:如何确保只有一个插入/更新PER DOWNLOAD插入到数据库中,或者至少,如何防止PHP脚本多次执行?
UPDATE
firebug中的问题截图:
一个要求:
两个要求:
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(); ?>
所以你的超链接可能如下所示:
<a href='download.PHP?token={some-token}&f={$item['name']}&t={$type}' target='_blank'>{$item['name']}</a>
<?PHP session_start(); if (!isset($_REQUEST['token']) die(); // or fail better if (!isset($_SESSION['oneTimeTokens'][$_REQUEST['token']) die(); // or fail better if ($_SESSION['oneTimeTokens'][$_REQUEST['token']=='used') die(); // or fail better $_SESSION['oneTimeTokens'][$_REQUEST['token']='used'; // we're good from this point
这可以解决你的问题的影响,虽然不是双重运行本身.但是,既然你想确保一个链接只触发一次事件,那么你可能会以某种形式实现它,因为这是保证生成的任何链接都有一个我能想到的实际使用寿命的唯一方法. .
<?PHP $tokenID = {random id generation here}; $_SESSION['oneTimeTokens'][$tokenID] = 'not used';
我还会在某个地方放置一个清理例程来删除所有使用过的令牌.此外,超过一定年龄的令牌到期并不是一个坏主意,但我认为这解释了它.
以上是脚本宝典为你收集整理的PHP PDF下载脚本正在执行两次全部内容,希望文章能够帮你解决PHP PDF下载脚本正在执行两次所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。