2017-03-27 5 views
1

Um den Kontext zu erklären, habe ich eine CSV-Datei, durch die ich looping bin.PDO Anfrage funktioniert 1/4 mal

Ich habe bereits mit dem folgenden Code überprüft, ich bin eigentlich jede Zeile meiner CSV-Datei bereit.

if (file_exists($file)){ 

    $fic = fopen($file, 'rb'); 
    $linecount = 0; 

    for ($ligne = fgetcsv($fic, 1024,";"); !feof($fic); $ligne = fgetcsv($fic, 1024,";")) { 
     $linecount++; 
    } 
} 
else { 
/*do smth*/ 
} 
echo $linecount; 

Aber wenn ich ersetzen $ linecount ++ mit dem, was ich meinen Code wirklich tun möchte:

$codeArticle = $ligne[0]; //Code Article 
$nomArticle = $ligne[1]; //Nom Article 
$refGamme = $ligne[2]; //Référence Gamme 
$nomGamme = $ligne[3]; //Nom Gamme 
$codeSSRef = $ligne[4]; //Code Sous Référence 
$libelleSSRef = $ligne[5]; //Libellé Sous Référence 

$queryGammes = "INSERT INTO Gamme VALUES('$refGamme','$nomGamme');"; 
$querySSRef = "INSERT INTO SS_Ref VALUES('$codeSSRef','$libelleSSRef');"; 
$queryProduits = "INSERT INTO Produit VALUES('$codeArticle','$nomArticle',NULL,'$refGamme','$codeSSRef');"; 
$result = $pdo->query($queryGammes); 
$result = $pdo->query($querySSRef); 
$result = $pdo->query($queryProduits); 

ich mit diesem Code kein Fehler bekam läuft, aber wenn ich mir in meine db (mysql) ich nur habe 339 Gesamtzeilen in der Tabelle namens Produit, wo ich 1 Zeile pro CSV-Zeile haben sollte. Diese Zeilen sind wirklich toll, die Anfragen laufen gut, aber ich kann nicht herausfinden, warum dieser Code nicht jede Zeile meiner Datei in meine DB einfügt.

Bitte um Rat fragen? Ich bin hier wirklich fest und es ist wichtig, damit ich einen Ratschlag nehme.

+1

diejenigen tun, die nicht eingeführt haben, enthalten ' ''? –

+0

Erstellen von SQL-Abfragezeichenfolgen aus Eingabe ist nie eine gute Idee. Es kann zu allem führen, von ungültigem SQL (wenn jemand den Namen O'Leary hat, wird es das generierte SQL brechen) zu SQL-Injection-Angriffen. Ich wette, dass viele Ihrer Probleme verschwinden werden, wenn Sie Ihren SQL-String-Baucode durch korrekt vorbereitete Anweisungen ersetzen. – GordonM

+0

"Ich gehe keinen Fehler mit diesem Code" - Dann schauen Sie sich bitte an, wie man Fehlermeldungen aus PDO herausquetscht ] (http: // Stapelüberlauf.com/questions/3726505/how-to-squeeze-Fehlermeldung-out-of-pdo # 3726526). –

Antwort

0

Thx an alle Antworten, die ich bekam ich eine Lösung gefunden, zuerst ich parametrisierte Abfragen verwendet, wie von @maxpovver vorgeschlagen (ich klebte das bekam er gab) und @ Chris Travers.

Danke an @ Álvaro González und @Ihr Common Sense Ich habe es geschafft, PDO Errors zu drucken, die mir sagten, dass es einige Probleme mit Specials Chars gab. Das Setzen von PDO-Zeichensatz auf utf8, wie von @Ihr Common Sense vorgeschlagen, war nicht genug, um das Problem am Eingang zu ändern, aber es löste sich beim Beenden: Spezielle Zeichen werden gut gedruckt, wenn ich sie aus meiner Datenbank abrufe.

Zur Lösung des Problems Ich hatte die utf8_encode PHP-Funktion zu verwenden:

$result = $queryGammes->execute(array(
    "refGamme"=> $refGamme, 
    "nomGamme"=> utf8_encode($nomGamme)) 
); 
+0

Nein, bitte. Eine Lösung für das Kodieren von Problemen, die utf8_encode() beinhaltet, ist fast immer falsch. Haben Sie Beweise, dass Sie ISO-8859-1 verwenden? –

+0

Meine Datenbank verwendet utf8mb4_unicode_ci, aber für die Website, die ich nicht kenne, werde ich versuchen, es herauszufinden. –

0

Prüfliste:

  1. Sie sind nicht Ihre Eingabe Hygienisierung, so dass der erste Platz ist würde ich aussehe. Am wahrscheinlichsten und robustesten ist es, auf die parameterized query Syntax von PDO zu wechseln.
  2. Nun, unter der Annahme, dass das Problem nicht behoben wird, ist der nächste Schritt, die Zeilen sorgfältig zu betrachten, die gegen die Zeilen einfügen, die dies nicht tun. Ich würde die ersten paar Reihen nehmen und sie mit denen vergleichen, die das nicht tun.
  3. Ich würde einzigartige Einschränkungen betrachten. Verstöße können hier Nachrichten in das MySQL-Protokoll werfen. Überprüfe das zuerst.
2

Ich bin fast sicher, dass Sie Probleme haben, weil Werte direkt in sql eingefügt werden. Hier ist, was Sie sollten stattdessen tun:

if (file_exists($file)){ 

    $fic = fopen($file, 'rb'); 
    $linecount = 0; 
    // generate prepared statements only once and reuse them in loop 
    $queryGammes = $pdo->prepare("INSERT INTO Gamme VALUES(:refGamme,:nomGamme);"); 
    $querySSRef = $pdo->prepare("INSERT INTO SS_Ref VALUES(:codeSSRef,:libelleSSRef);"); 
    $queryProduits = $pdo->prepare"INSERT INTO Produit  
       VALUES(:codeArticle,:nomArticle,NULL,:refGamme,:codeSSRef);"); 
    for ($ligne = fgetcsv($fic, 1024,";"); !feof($fic); $ligne = fgetcsv($fic, 1024,";")) { 
     $codeArticle = $ligne[0]; //Code Article 
     $nomArticle = $ligne[1]; //Nom Article 
     $refGamme = $ligne[2]; //Référence Gamme 
     $nomGamme = $ligne[3]; //Nom Gamme 
     $codeSSRef = $ligne[4]; //Code Sous Référence 
     $libelleSSRef = $ligne[5]; //Libellé Sous Réfé 
     // execute queries using generated statements, not $pdo directly 
     $result = $queryGammes->execute(array("refGamme"=> $refGamme, "nomGamme"=> $nomGamme)); 
     $result = $querySSRef->execute(array("codeSSRef"=>$codeSSRef, "libelleSSRef"=>$libelleSSRef)); 
     $result = $queryProduits->execute(array("codeArticle"=>$codeArticle, "nomArticle"=>$nomArticle, "refGamme"=> $refGamme,"codeSSRef"=>$codeSSRef)); 
    } 
} 

Sie können es auch machen, ohne benannte Parameter zu verwenden, aber ich empfehle nicht, das zu tun, weil ein solcher Code weniger lesbar ist (und es wird schwieriger sein, sich daran zu erinnern, was es später der Fall ist):

if (file_exists($file)){ 

    $fic = fopen($file, 'rb'); 
    $linecount = 0; 
    // generate prepared statements only once and reuse them in loop 
    $queryGammes = $pdo->prepare("INSERT INTO Gamme VALUES(?,?);"); 
    $querySSRef = $pdo->prepare("INSERT INTO SS_Ref VALUES(?,?);"); 
    $queryProduits = $pdo->prepare"INSERT INTO Produit  
       VALUES(?,?,NULL,?,?);"); 
    for ($ligne = fgetcsv($fic, 1024,";"); !feof($fic); $ligne = fgetcsv($fic, 1024,";")) { 
     $codeArticle = $ligne[0]; //Code Article 
     $nomArticle = $ligne[1]; //Nom Article 
     $refGamme = $ligne[2]; //Référence Gamme 
     $nomGamme = $ligne[3]; //Nom Gamme 
     $codeSSRef = $ligne[4]; //Code Sous Référence 
     $libelleSSRef = $ligne[5]; //Libellé Sous Réfé 
     // execute queries using generated statements, not $pdo directly 
     $result = $queryGammes->execute(array($refGamme, $nomGamme)); 
     $result = $querySSRef->execute(array($codeSSRef, $libelleSSRef)); 
     $result = $queryProduits->execute(array($codeArticle,$nomArticle,$refGamme,$codeSSRef)); 
    } 
} 
+0

Vielen Dank für diese Antwort! Es verbesserte meinen Code sehr, aber änderte das Ergebnis nicht, aber thx zu anderen Antworten ich könnte einen Weg gefunden haben! –

+0

Dies hat immer noch einige Probleme, nämlich dass Sie keine Fehlerbehandlung durchführen. Die Methoden prepare() und execute() können fehlschlagen und entweder false zurückgeben oder eine Ausnahme auslösen (je nachdem, wie PDO konfiguriert ist). So oder so, es muss ein Fehlerkorrekturcode hinzugefügt werden (entweder nach erfolgreichen Rückgabewerten von prepare() und execute() suchen oder try/catch zum Behandeln von Ausnahmen verwenden) – GordonM

+0

Ich habe bereits einige try catch hier hinzugefügt –

Verwandte Themen