freshman2017
Goto Top

TXT zu MySQL php

Guten Morgen liebe Gemeinde!

Ich würde gerne nachfolgendes PHP Skript nutzen um eine MySQL Tabelle uptaden zu können:

(die txt Datei liegt im gleichen Verzeichnis bei einem Webhoster als das PHP Skript)

<?php
$dsn = 'mysql:dbname=sample;host=localhost';  
$user = 'test';  
$password = 'test';  
 
try {
    $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();  
}
 
$file= new SplFileObject('data.txt');  
while(!$file->eof())
{
    $line=$file->fgets();
    list($name,$lname,$birth)=explode(';',$line);  
    
    $sth = $dbh->prepare('INSERT INTO customers values(NULL,?,?,?)');  
    $sth->bindValue(1,$name,PDO::PARAM_STR);
    $sth->bindValue(2,$lname,PDO::PARAM_STR);
    $sth->bindValue(3,$birth,PDO::PARAM_STR);
    $sth->execute();   
}
 
?>

Wenn ich die Daten im Skript mit den Datenbank-Daten vom Hoster anpasse klappt es irgendwie nicht - er importiert nichts.

Woran könnte es liegen?

Content-ID: 2692616224

Url: https://administrator.de/contentid/2692616224

Ausgedruckt am: 21.11.2024 um 21:11 Uhr

colinardo
colinardo 05.05.2022 aktualisiert um 13:41:45 Uhr
Goto Top
Servus.
Schalte doch einfach mal das Error-Reporting am Anfang des Skriptes ein dann siehst du im Klartext was da schief läuft ...
error_reporting(E_ALL);
ini_set('display_errors','On');  
Grüße Uwe

btw. Zeile 10 ist gefährlich in der Production, das zeigt dem User bei einer Exception wie nicht verfügbarem Server im schlimmsten Fall das verwendete Datenbank-Passwort im Klartext an. Des weiteren müsstest du im Catch Teil dann auch das PHP Skript mit die() oder exit korrekterweise beenden, denn ohne Verbindung zur DB sind keine weiteren Aktionen mit dieser möglich.
freshman2017
freshman2017 06.05.2022 um 17:31:40 Uhr
Goto Top
Zitat von @freshman2017:

Guten Morgen liebe Gemeinde!

Ich würde gerne nachfolgendes PHP Skript nutzen um eine MySQL Tabelle uptaden zu können:

(die txt Datei liegt im gleichen Verzeichnis bei einem Webhoster als das PHP Skript)

<?php
$dsn = 'mysql:dbname=sample;host=localhost';  
$user = 'test';  
$password = 'test';  
 
try {
    $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();  
}
 
$file= new SplFileObject('data.txt');  
while(!$file->eof())
{
    $line=$file->fgets();
    list($name,$lname,$birth)=explode(';',$line);  
    
    $sth = $dbh->prepare('INSERT INTO customers values(NULL,?,?,?)');  
    $sth->bindValue(1,$name,PDO::PARAM_STR);
    $sth->bindValue(2,$lname,PDO::PARAM_STR);
    $sth->bindValue(3,$birth,PDO::PARAM_STR);
    $sth->execute();   
}
 
?>

Wenn ich die Daten im Skript mit den Datenbank-Daten vom Hoster anpasse klappt es irgendwie nicht - er importiert nichts.

Woran könnte es liegen?

Kann das Skript denn noch anders, ohne das Kennwörter im Klartext angezeigt werden, aussehen?
colinardo
colinardo 06.05.2022 aktualisiert um 17:36:28 Uhr
Goto Top
Zitat von @freshman2017:
Kann das Skript denn noch anders, ohne das Kennwörter im Klartext angezeigt werden, aussehen?
Ja, lass die Ausgabe der Exception Message mit dem echo weg, fürs erste Debugging ist das OK aber nicht anschließend für den öffentlichen Produktivbetrieb
tk1234
Lösung tk1234 08.05.2022 um 13:09:41 Uhr
Goto Top
Woran könnte es liegen?

An vielem:
  • Wird die txt-Datei korrekt ausgelesen? (wobei das eine CSV-Datei zu sein scheint, deswegen würde ich aber die entsprechende Methode zum Auslesen solcher Dateien verwenden)
  • Welche Spalten hat die Zieltabelle? Bei einem INSERT sollten immer die zu füllenden Spalten angegeben werden, dann funktioniert der Zukunft auch wenn mal eine zusätzliche Spalte angelegt wird und das NULL für die ID(?) ist nicht mehr nötig. (dass das Error-Reporting von PHP eingeschaltet sein sollte, schrieb colinardo ja schon)
  • Meldet die Datenbank einen Fehler? Je nach PHP-Version ist es nötig beim Aufbau der Verbindung noch PDO::ATTR_ERRMODE auf PDO::ERRMODE_EXCEPTION zu setzen damit Fehler gemeldet werden (ist ab PHP 8.0.0 der Standardwert)

Ein paar weitere Hinweise noch:
  • im DSN fehlt noch die Angabe für den Charset, da sollte noch ein »;charset=utf8mb4« stehen damit definiert ist wie die Daten geliefert werden und du nicht von einem Standardwert (der sich auch ändern kann!) abhängig bist
  • bei PDO würde ich die Möglichkeit nutzen bei prepared Statement benannte Parameter verwenden zu können, das macht den Code besser lesbar als Rudel von Fragezeichen (drei mögen noch gehen, darüber wird es aber schnell unübersichtlich)
  • in $birth dürfte noch der Zeilenumbruch stehen, die Datenbank scheint das zwar nicht zu stören, entfernen solltest du ihn trotzdem (bzw. die Methode zum lesen von CSV-Dateien verwenden, siehe oben)
  • die prepare-Zeile gehört vor die while-Schleife, das prepare muss nur einmal gemacht werden, nur das execute erfolgt dann für jeden Datensatz; wenn du nicht bindValue sondern bindParam verwendest, kannst du die Zeilen auch vor die Schleife setzen (ich bevorzuge die Werte direkt an execute zu übergeben und nicht bind* zu verwenden, aber falsch ist es so nicht)
  • das ?> solltest du weg lassen wenn es sich um eine reine Code-Datei handelt die nicht noch HTML dahinter ausgibt o.ä. (verhindert die ungewollte Ausgabe von Zeilenumbrüchen o.ä.)

Gruß
Tobias
freshman2017
freshman2017 10.05.2022 um 20:34:24 Uhr
Goto Top
Vielen lieben Dank für die bisherigen Antworten. Ich habe jetzt durch eine OnlineRecherche ein Skript gefunden, was genau meinen Ansprüchen entspricht.

Allerdings bräuchte ich einmal Hilfe bei der Anpassung. Kann mir da jemand helfen?

Meine TXT Datei sieht wie folgt aus:

name;lname;birth;
Max;Muster;01.01.1900;

$db_connection = new mysqli("HOST","DB_USER","DB_PASS","DB");   
// make mysqli connection to DB 
$query = $db_connection->prepare("INSERT INTO yourtable (column1,column2) VALUES (?,?)");   
$data = scandir('/PATH/TO/READ');   
// Scan the dir your files are in foreach ($data as $datas) { if (0 === strpos($datas, 'logdata')) { echo $datas."<br />"; 
 //Show all the files that beginn with logdata $file = 'PATH/TO/FILE/'.$datas;  
unset($file);
 //DELETE THE FIRST LINE IF FILE CONTAINS A HEADLINE ELSE DELETE THIS LINE foreach ($file as $line) { $column = explode("\t", $line);  
// \t stands for tab-delimited, change it to what ever delimites your file (f.e. ; , . ) 
$example = $column;
 // get content of first column $example1 = $column[1]; 
// get content of second column 
// ..... 
$query->bind_param('ss',$example, $example1) $query->execute(); }}}