PHP, PDO und SQLSRV wird mehrmals in einer INSERT-Anweisung ausgeführt

8

Ich benutze PDO und PHP seit einiger Zeit mit MySQL und Apache Servern. Ich bin kürzlich beauftragt worden, eine ältere Webanwendung für ein Unternehmen in ein neues Setup umzuwandeln. Das alte Setup ist ein Standard-Linux-Web-Stack (Apache / PHP / MySQL / Filezilla) und das neue Setup wird ein Windows-Server 2003 mit IIS / PHP (schnelle CGI-Installation) / SQL Server 2003 / No FTP sein.

Ich habe fast alles außer einer Konvertierung einer MySQL-Anweisung, um eine Tabelle mit Dateizugriffsinformationen zu aktualisieren. Die Verwendung von PDO mit dem SQLSRV-Treiber und das Ausführen einer insert-Anweisung innerhalb eines PHP-Skripts zum Herunterladen von Dateien fügt mehrere Datensätze in die SQL-Tabelle ein.

Die download.php gibt mehrere Abfragen an den SQL Server aus. Einmal um nach der Datei Existenz und Variablen in einer Tabelle zu suchen, und DANN aktualisiert eine andere Tabelle mit den Zugriffsinformationen.

  

SIEHE UNTEN FÜR download.php CODE

Das Debugging zeigt den Ausdruck / das Echo von $ count als 1. Das Überprüfen der SQL Server-Datensätze zeigt jedoch immer MEHR als eins eingefügt. Manchmal ist es nur eine zusätzliche Zeile für insgesamt zwei, aber manchmal ist es so hoch wie vier EXTRA-Anweisungen eingefügt werden. $ count wird in jedem Fall als 1 angezeigt.

Dieses spezielle PHP-Skript verifiziert Informationen vor dem Aufruf dieser insert-Anweisung gegen die SQL-Datenbank. Erstens, die Überprüfung der Authentifizierung für den Dateizugriff (erfolgreich), überprüft die Datei Existenz (erfolgreich), aktualisiert dann die Zugriffstabelle mit Informationen für den Download (ERROR) und schließlich dient die PDF für den Benutzer (erfolgreich).

Wenn ich die INSERT-Anweisung manuell in Query Analyzer ausstelle, ist sie erfolgreich und funktioniert wie erwartet; Es fügt jedesmal eine Zeile ein. Der Fehler scheint mit SQLSRV oder PDO-Implementierung der execute () zu sein.

Ich habe stackoverflow, serverfault und das allmächtige Google nach Informationen diesbezüglich gesucht. Die einzigen Ergebnistypen werden zurückgegeben, wenn Benutzer mehrere Abfragen / Einfügungen in einer Anweisung ausführen / ausführen müssen. Wo ist mein Problem das Gegenteil? Ich möchte nur eine Insert-Anweisung ausführen, aber mehr als eine wird immer ausgeführt.

Frage ist: Warum passiert das und wie kann ich verhindern, dass der Mehrfacheinsatz passiert?

UPDATE PRO REQUEST

Der Code, der auf diese Datei zugreift, ist ein einzelner Link von einer anderen Webseite. Die Seite listet aktuelle Dateien auf, auf die der Benutzer zugreifen darf, und stellt Links zum download.php-Skript zur Verifizierung, Aktualisierung und tatsächlichen Bereitstellung der PDF bereit.

View page hat eine Liste von Links (in einer for-Schleife gedruckt), die wie folgt angeordnet sind:

%Vor%

Wenn der Benutzer auf diesen Link klickt, wird das folgende Skript zusätzlich zu dem oben genannten Code für download.php ausgeführt. Es dient erfolgreich die PDF-Datei. Der Inhalt wird von download.php als PHP-Header / Inline-PDF gesendet:

  

SIEHE UNTEN FÜR CODE

Wenn Sie sich die Serverprotokolle ansehen, wird zwei GET-Anforderungen an die Datei download.php angezeigt:

%Vor%

Ich habe in Firefox, Opera und IE (6-9b) getestet und die Ergebnisse sind die gleichen.

UPDATE ZWEI

Hier können Sie die gesamte download.php Datei ablegen:

%Vor%     
PenguinCoder 14.02.2012, 15:59
quelle

3 Antworten

1

Sie kommentieren, dass das Download-Skript zweimal aufgerufen wird und beendet werden sollte, wenn der korrekte Wert nicht gefunden wird. Dies ist möglicherweise nicht der Fall, weil Sie PDOStatements rowCount() missbrauchen, um nach gefundenen Dateien zu suchen. Diese Methode soll die Anzahl der betroffenen Zeilen für DELETE-, UPDATE- oder INSERT-Anweisungen zurückgeben, aber nicht SELECT .

  

Wenn die letzte SQL-Anweisung, die vom zugeordneten PDOS-Statement ausgeführt wurde, eine SELECT-Anweisung war, können einige Datenbanken die Anzahl der von dieser Anweisung zurückgegebenen Zeilen zurückgeben. Dieses Verhalten ist jedoch nicht für alle Datenbanken garantiert und sollte nicht für portable Anwendungen verwendet werden.     Ссылка

Sie fahren fort mit:

  

Bei den meisten Datenbanken gibt PDOStatement :: rowCount () nicht die Anzahl der Zeilen zurück, die von einer SELECT-Anweisung betroffen sind. Verwenden Sie stattdessen PDO :: query (), um eine SELECT COUNT (*) -Anweisung mit den gleichen Prädikaten wie Ihre beabsichtigte SELECT-Anweisung auszugeben, und verwenden Sie anschließend PDOStatement :: fetchColumn (), um die Anzahl der zurückzugebenden Zeilen abzurufen.

Wenn Sie das download.php-Skript zweimal aufrufen - einmal mit falschen Dateiwerten (die Ihren Regex-Test bestehen) und einmal mit korrekten Werten, ist es durchaus möglich, dass Sie zweimal einfügen, obwohl Sie nur herunterladen einmal.

    
Farray 14.02.2012 17:41
quelle
1

Wenn Sie Apache mod_rewrite verwenden, wird die Seite in der Tat zweimal geladen. Verwenden Sie als Beispiel den folgenden Code auf Ihrer Indexseite:

%Vor%

Ohne eine Umleitung zu verwenden, wird der Ausgang bei jedem Refresh um 1 erhöht. Fügen Sie nun eine .htaccess-Datei mit den folgenden hinzu:

%Vor%

Jede Aktualisierung erhöht die Seite um zwei. Ich habe das gleiche mit einer einzigen INSERT Abfrage versucht und das gleiche passiert: mit .htaccess werden zwei Zeilen eingefügt; Ohne wird eine Zeile eingefügt.

Also, wenn Sie mod_rewrite verwenden und download.php betrifft, dann glaube ich, dass dies das Problem ist.

    
MichaelRushton 30.03.2012 12:00
quelle
1

Tipp: Entfernen Sie ?> vom Ende ALLER Ihrer PHP-Dateien. Gelegentlich erhalten Sie danach einen unsichtbaren Platz oder eine neue Zeile, und wenn Sie ein binäres Format wie PDF ausgeben, wird es ein Teil der PDF und macht es korrupt. (Daher Browser / PDF-Reader hängen.)

    
jornare 02.04.2012 08:14
quelle

Tags und Links