title: PHP, PDO and SQLSRV executes multiple times on one INSERT statement
body: <p>I've been using PDO and PHP for a while with MySQL and Apache servers. I've recently been tasked with converting a legacy web application for a business to a new setup. The old setup is a standard Linux web stack (Apache/PHP/MySQL/Filezilla) and the new setup will be a Windows server 2003 with IIS/PHP(fast cgi install)/ SQL Server 2003/No FTP. </p>
  
  <p>I have nearly everything working except for a conversion of a MySQL statement to update a table with file access information. Using PDO with SQLSRV driver and executing an insert statement inside a 'file download' PHP script, inserts multiple records into the SQL table. </p>
  
  <p>The download.php DOES issues multiple queries to the SQL server. Once to check for the file existence and variables in one table, and THEN updates another table with the access information. </p>
  
  <blockquote>
    <p>SEE BELOW FOR download.php CODE</p>
  </blockquote>
  
  <p>Debugging shows the print/echo of $count as 1. Checking the SQL server records however, always shows MORE than one inserted. Sometimes it is just one extra row for a total of two, but other times it is as high as four EXTRA statements being inserted. $count remains shown as 1, in every case.</p>
  
  <p>This particular PHP script verifies information against the SQL database prior to calling this insert statement. First, the verification of authentication for the file access(succeeds), verifies the file existence(succeeds), then updates the access table with information for the download (ERROR) and finally serves the PDF to the user (succeeds). </p>
  
  <p>When I issue the INSERT statement manually into Query Analyzer, it succeeds and works as expected; it inserts one row every time. The error seems to be with SQLSRV or PDO implementation of the execute(). </p>
  
  <p>I have searched on stackoverflow, serverfault and the almighty Google for information regarding this. The only types of results returned where users needing to execute multiple queries/inserts in one statement/execute. Where's my issue is the opposite; I wish to only execute ONE insert statement however, more than one is always executed. </p>
  
  <p>Question is: Why is this happening and how can I prevent the multiple insert from happening?</p>
  
  <p><strong>UPDATE PER REQUEST</strong></p>
  
  <p>The code that accesses this file is one singular link from another web page. The page lists current files the user is allowed to access and presents links to the download.php script for the verification, update and actual serving of the PDF. </p>
  
  <p>View page has a list of links (printed in a for loop) arranged like :</p>
  
  <pre><code>&lt;a href='download.php?f={$item['name']}&amp;t={$type}' target='_blank'&gt;{$item['name']}&lt;/a&gt;
  </code></pre>
  
  <p>When the user clicks on that link, the script below is what runs in addition to the other code above for download.php. It successfully serves the PDF file. The content is being sent by download.php as a PHP header/inline PDF:</p>
  
  <blockquote>
    <p>SEE BELOW FOR CODE</p>
  </blockquote>
  
  <p>Looking at the server logs shows <strong>two</strong> GET request to the download.php file:</p>
  
  <pre><code>2012-02-14 17:44:37 W3SVC1785071458 172.17.31.254 GET /download.php f=06304844-1A.pdf&amp;t=av 4090 - 172.17.31.112 Mozilla/5.0+(Windows+NT+6.1)+AppleWebKit/535.7+(KHTML,+like+Gecko)+Chrome/16.0.912.77+Safari/535.7 200 0 0
  2012-02-14 17:44:37 W3SVC1785071458 172.17.31.254 GET /download.php f=06304844-1A.pdf&amp;t=av 4090 - 172.17.31.112 Mozilla/5.0+(Windows+NT+6.1)+AppleWebKit/535.7+(KHTML,+like+Gecko)+Chrome/16.0.912.77+Safari/535.7 200 0 0
  </code></pre>
  
  <p>I have tested in Firefox, Opera, and IE (6-9b) and the results are the same.</p>
  
  <p><strong>UPDATE TWO</strong></p>
  
  <p>Putting the entire download.php file here:</p>
  
  <pre><code>&lt;?php
  session_start();
  require("cgi-bin/auth.php");
  
  // Don't timeout when downloading large files
  @ignore_user_abort();  
  @set_time_limit(0);  
  
  //error_reporting(E_ALL); 
  //ini_set('display_errors',1);
  
  function getfile() {
      require('cgi-bin/connect_db_pdf.php');
      //Verify information 
      if (!isset($_GET) || !isset($_GET['f']) || !isset($_GET['t'])) {
          echo "Nothing to do!";
          exit(0);
  
      }
  
      //Update variables
      $vuname = strtolower(trim($_SESSION['uname']));
      $file = trim($_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)) {
          echo "Non conforming values";
          exit(0);
      }
  
      try {
  
          $sQuery = "SELECT * FROM pdf_info WHERE PDF_name=:file AND PDF_type=:type";
  
          $statm = $conn-&gt;prepare($sQuery);
          $statm-&gt;execute(array(':file'=&gt;$file,':type'=&gt;$type));
          $result = $statm-&gt;fetch();
          $count = $statm-&gt;rowCount();
          $sQuery = null;
          $statm = null;
  
          if ($count == 1 ){ //File was found in the database so let them download it. Update the time as well
  
              $sQuery = "INSERT INTO access (PDF_name,PDF_type, PDF_time, PDF_access) VALUES (:file, :type, GetDate(), :vuname)";
  
              $statm = $conn-&gt;prepare($sQuery);
              $statm-&gt;execute(array( ':vuname'=&gt;$vuname, ':file'=&gt;$file, ':type'=&gt;$type));
              $count = $statm-&gt;rowCount();
              $sQuery = null;
              $statm = null;
  
              $sQuery = "UPDATE pdf_info SET last_view=GetDate(),viewed_uname=:vuname WHERE PDF_name=:file AND PDF_type=:type";
  
              $statm = $conn-&gt;prepare($sQuery);
              $statm-&gt;execute(array( ':vuname'=&gt;$vuname, ':file'=&gt;$file, ':type'=&gt;$type));
              $sQuery = null;
              $statm = null;
  
              //$result is from FIRST SELECT query outside this 'if' scope.
              $file_loc = $result['floc'];
              $file_name = $result['filename'];
  
              $fileh = fopen($file_loc,'rb');//Send content to browser as inline PDF
              header("Content-Type: application/pdf"); 
              header("Pragma: no-cache");  
              header("Cache-Control: must-revalidate, post-check=0, pre-check=0");  
              header("Content-Length: " . filesize($file_loc));  
              header("Accept-Ranges: bytes");
              header("Content-Disposition: inline; filename={$file_name}");  
  
              while (!feof($fileh)) { 
                  echo(@fgets($fileh, 8192)); 
              } 
  
              fclose ($fileh); 
              exit(0);
  
              } else { //We did not find a file in the database. Redirect the user to the view page.
                  header("Location: view.php");
              }
  
              }   catch(PDOException $err) {//PDO SQL error. 
              //echo $err;
              header('Location: error.php');
              exit(0);
           }
  }
  
  getfile();
  
  ?&gt;
  </code></pre>