I have a web application using PHP and PDO with prepared SQLSRV statements to display file links for users to download. The internal PHP script 'download.php' checks the various elements before uploading a PDF file to the user for download. Then the download.php file should update several SQL tables and serve the PDF file for the user.
Please read my previous question and troubleshooting completed there if you need more information.
After troubleshooting, the error that I was thinking about was (and therefore the previous question I asked) was incorrect. My script download is done several times for each file download.
I searched server logs and while debugging with Firebug, I see that my download.php script makes several GET requests to the server. Sometimes a script completes only once as expected. In other cases, the script executes three to four requests for one click of the download link.
Now that I understand more fully what is happening with the error, I need a little help in fixing it. I need to prevent the script from running several times and thus update the SQL table with records that are within a few milliseconds of each other.
The browse page checks the SQL database for files that the current user is allowed to access and displays a list of links:
<a href='download.php?f={$item['name']}&t={$type}' target='_blank'>{$item['name']}</a>
Since values ββare required to download the download.php script, I cannot change the request to $ _POST instead of $ _GET.
What I tried:
Check / set the session variable for the load state before getfile() , which is disabled just before exit(0)
Putting SQL statements in a separate PHP file and requiring that
Adding sleep(1) after getfile()
Comment header information / PDF
The first three measures did not help prevent the double / triple loading of the PHP script. However, the last measure prevents double / triple execution of the PHP script, but, of course, PDF is never delivered to the client browser!
Question How can I guarantee that only one PER DOWNLOAD ONE insert / update is inserted into the database, or at least how can I prevent the PHP script from executing multiple times?
UPDATE
Screenshot with a question in firebug:
One request: 
Two queries: 
download.php script
<?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(); ?>