PHP Daten aus txt zuordnen und neue Tabelle erstellen

felsi

Banned
Registriert
Mai 2007
Beiträge
556
Hallo,

ich hänge gerade mit folgendem Problem fest und komme auch gedanklich nicht weiter.

Ich habe eine .txt Datei, die Daten wie folgt enthält:

Code:
sku; customer; group; qty; price
123;ABC;0;1;25
123;DEF;0;1;27
123;GHI;0;1;26
456;ABC;0;1;28
456;DEF;0;1;27
789;GHI;0;1;30

Nun lese ich die Datei mittels PHP ein:

Code:
$handle = fopen($file, "r");

do {
    $line = fgets($handle);
    
    $data = explode(";", $line);
    
        $sku = $data[0];
        $customer = $data[1];
        $group = $data[2];
        $price = $data[4];
        
        print_r($data);
    
    } while ($line !== false);

Ergebnis:

Code:
Array ( [0] => 123 [1] => ABC [2] => 0 [3] => 1 [4] => 25 ) 
Array ( [0] => 123 [1] => DEF [2] => 0 [3] => 1 [4] => 27 )
usw.

Soweit so gut.

Problem: Den Werten muss ich nun basierend auf "customer" einen anderen Wert aus einer mySQL Tabelle zuordnen. Die Tabelle hat folgende Spalten:

Code:
entity_id | value
500 | ABC
600 | DEF
700 | GHI
800 | ABC

Meine Idee war es, eine neue Tabelle zu erstellen, die am Ende dann so aussieht:

Code:
sku | customer | group | qty | price | entity_id
123 | ABC | 0 | 1 | 25 | 500
123 | DEF | 0 | 1 | 27 | 600
123 | GHI | 0 | 1 | 26 | 700
456 | ABC | 0 | 1 | 28 | 500
456 | DEF | 0 | 1 | 27 | 600
789 | GHI | 0 | 1 | 30 | 700
123 | ABC | 0 | 1 | 25 | 800
456 | ABC | 0 | 1 | 28 | 800

Die beiden letztn Zeilen sind im Prinzip nicht nur "einfache Zuordnung" sondern neu erstellt, da es "customer" (in diesem Beispiel: ABC) mit verschiedenen "entity_id" geben kann.

Ich scheitere allerdings bereits am Erstellen der neuen Tabelle aus den vorhandenen Daten, da ich in der "do while" Schleife feststecke, wenn ich dort "SELECT 'entity_id' FROM customer_entity_varchar WHERE value = :customer" ausführe. Ich hoffe, ihr wisst was ich meine, und könnt mir auf die Sprünge helfen.

Oder geht das überhaupt nicht so, wie ich es vorhabe?

Danke
 
Also du willst entweder
Code:
$data[5]=$db->query('select entitiy from ... where ...=:customer');
$entity=$data[5];
oder aber du willst das in eine SQL-Tabelle eintragen (das wäre dann 'insert into ...').

Wenn du da ne neue Textdatei erstellen willst, dann brauchst du natürlich ein fopen vor der Schleife und ein implode und ein fputs in der Schleife.
 
Hallo, danke schon mal, aber könntest du das bitte noch mal etwas ausführen? Also in meiner do - Schleife habe ich nun folgendes (ich versuche PDO zu nutzen):

Code:
$stmt = $db->prepare("SELECT `entity_id` FROM `customer_entity_varchar` WHERE value = :customer");
$data[5] = $stmt->execute($customer);
echo($data[0] . " | " . $data[1] . " | " . $data[2] . " | " . $data[3] . " .  $data[5] .  <br>");

Es werden mir nun zwar nicht mehr alle Felder selektiert, aber mein gewünschtes Ergebnis erhalte ich trotzdem nicht. $data[5] ist leer und irgendwie werden mir auch Felder selektiert, die überhaupt nicht in $customer vorkommen.

Also so auf dem Schlauch wie heute stand ich schon lang nicht mehr.
 
Das wird nicht funktionieren https://www.php.net/manual/de/pdostatement.execute.php gibt entweder true oder false zurück (ich hoffe ja true).

Was du dann brauchst ist https://www.php.net/manual/de/pdostatement.fetch.php oder fetchAll oder fetchColumn.

Code:
$stmt = $db->prepare("SELECT `entity_id` FROM `customer_entity_varchar` WHERE value = :customer");
if(!$stmt->execute(array(':customer'=>$customer)))
die("PDOerror");
$data[5]=$stmt->fetchColumn(0);
...

Tipp. Man kann PDO in den Exception mode setzten, dann merkst du sofort, wenn du SQL-Mist baust. https://www.php.net/manual/de/pdo.setattribute.php enthält da die Details.
 
  • Gefällt mir
Reaktionen: felsi
Danke dir, das sieht schon besser aus. Die entity_id wird nun richtig zugeordnet. Allerdings habe ich noch das bereits oben beschriebe Problem:

Beispiel: Meine txt Datei enthält nur einen einzelnen Eintrag:

Code:
sku | customer | group | qty | price
123 | ABC | 0 | 1 | 25

Die Tabelle "entity_id" enthält allerdings folgendes:
Diff:
entity_id | value
800 | ABC
900 | ABC

Als Ergebnis erhalte ich aktuell nur:
Code:
Array ( [0] => 123 [1] => ABC [2] => [3] => 1.0000 [4] => 25 [5] => 800 )

Benötigen würde ich allerdings beide Einträge aus der Tabelle, also:
Code:
Array ( [0] => 123 [1] => ABC [2] => [3] => 1.0000 [4] => 25 [5] => 800 )
Array ( [0] => 123 [1] => ABC [2] => [3] => 1.0000 [4] => 25 [5] => 900 )

Ist das machbar?
 
Ist mir ja schon unangenehm zu fragen, aber ich krieg's irgendwie nicht hin. Hättest du es mir noch mal im Ganzen?

Code:
$stmt = $db->prepare("SELECT `entity_id` FROM `customer_entity_varchar` WHERE value = :customer");
if(!$stmt->execute(array(':customer'=>$customer)))
die("PDOerror");
$data[5]=$stmt->fetchColumn(0);

Wenn ich es mit print_r($data); anschauen will, erhalte ich immer noch nur das einzelne Ergebnis. Und übrigens auch die leeren data[5]. Aber das sollte sich ja mit einem if check beheben lassen, bevor ich es in eine Tabelle schreibe.

Danke noch mal.
 
Code:
$stmt = $db->prepare("SELECT `entity_id` FROM `customer_entity_varchar` WHERE value = :customer");
erstellt das prepared statement
Code:
$stmt->execute(array(':customer'=>$customer)
bindet $customer an :customer und führt das statement aus, das passiert aber nicht in PHP sondern auf deinem SQL-Server (z.B. MySQL).

Nun musst du das Ergebnis abholen, das ergebnis kann eine einzelne Zeile oder aber 1.000.000 Zeilen sein, daher ist das $stmt ein Zeiger wie bei einem Dateihandle, bei dem man stück für Stück rausliest.
Jeder Aufruf von fetch/fetchColumn liefert eine Zeile (fetch die Zeile als Array, fetchColumn nur eine Spalte als Skalar). fetchAll würde alles auf einmal lesen, das kann schief gehen, wenn das Ergebnis größer als dein PHP Arbeitsspeicher ist.

fetch liefert (siehe PHP Doku) entweder ein Array oder false.
Wir rufen fetch auf und merken uns das Ergebnis in $erg und prüfen dann, ob $erg===false ist, wenn das der Fall ist, gibt es keine weiteren Ergebnisse.
Wenn $erg==array(...), dann schreibst du einfach eine komplette weitere Zeile in dein Ergebnisarray.

Code:
$stmt = $db->prepare("SELECT `entity_id` FROM `customer_entity_varchar` WHERE value = :customer");
if(!$stmt->execute(array(':customer'=>$customer)))
die("PDOerror");
while(($erg=$stmt->fetch())!==false){
$data[5]=$erg[0];
echo ... $erg[0] ...;
}
 
  • Gefällt mir
Reaktionen: felsi
Zurück
Oben