PHP csv auslesen und mysql werte zuordnen

Hallo Hancock,

damke für Deine Antwort

Hier die "momentane " csv
Art:Anzeige
Kategorie:226_1143 (1143)

titel [max. 80 Zeichen];untertitel [max. 80 Zeichen];beschreibung ;bild [nur Bildnamen zb. bild.jpg];verkauf_art [neu, gebraucht, defekt, neuwertig];homepage [unbedingt MIT http://];keywords [bis zu 5 Worte OHNE Komma besp: inserat kostenlos kaufinteresse];artikel_anzahl [nur Zahlen 0-9];topanzeige [ja oder freilassen];laufzeit [Anzahl der Tage: 3 ,5 ,7 ,14 ,14 ,30 ,30 ,30 ,45 ,60 ,90 ,90 ,100 ,180 ,365 ,365 ,];versand_text [max. 255 Zeichen];versand_preis [Dezimalzahl mit Dezimalkomma (Preis ohne Währung)];sofort_preis [Preis des Artikels(Dezimalzahl mit Dezimalkomma)ohne Währung];verkaufart [biete,suche,];


ich möchte sie später aber in Form von:
anzeige,kategoriemtitel [max. 80 Zeichen];untertitel [max. 80 Zeichen];beschreibung ;bild [nur Bildnamen zb. bild.jpg];verkauf_art [neu, gebraucht, defekt, neuwertig];homepage [unbedingt MIT http://];keywords [bis zu 5 Worte OHNE Komma besp: inserat kostenlos kaufinteresse];artikel_anzahl [nur Zahlen 0-9];topanzeige [ja oder freilassen];laufzeit [Anzahl der Tage: 3 ,5 ,7 ,14 ,14 ,30 ,30 ,30 ,45 ,60 ,90 ,90 ,100 ,180 ,365 ,365 ,];versand_text [max. 255 Zeichen];versand_preis [Dezimalzahl mit Dezimalkomma (Preis ohne Währung)];sofort_preis [Preis des Artikels(Dezimalzahl mit Dezimalkomma)ohne Währung];verkaufart [biete,suche,];
 
Hancock schrieb:
Also zuerst:
Code:
while(read){
if(1)do1();
elseif(2)do2();
elseif(3)do3();
}
ist ein sogenanntes Antipattern. Schreib es doch so, wie es ist.
Code:
read()
do1();
read();
do2();
...

Ach ja: Du weißt, was eine SQL-Injection ist?

Wenn ich mir dein Code so anschau: Kann es sein, dass du gar keine klassische CSV-Datei hast?
Zeile 1-4 enthält ja scheinbar irgendwelche Daten, die gar nicht nach Schema F laufen. (Zeile 3 ist leer?)

Könntest du uns mal eine Beispiel-CSV-Datei zeigen?

Hier mal eine Umsortierte Version deines Scripts
PHP:
	/* Was machst du mit den Informationen, die du hier bekommst?
if ($Daten[3] != "" && substr($Daten[3], 0, 4) != "http")
{
//Sonderzeichen,Leerzeichen und Umlaute ersetzen
$bild = preg_replace("/[^a-zA-Z0-9._-]/", "_", $Daten[3]);
if (!file_exists("member/csvupload/".$_SESSION['userid']."_".$_SESSION['username']."/".$bild.""))
{
$bild_error .= "Bild ".$Daten[3]." konnte nicht gefunden werden.<br> ";
}
}
else
{
$bild = "";
}*/

Hier prüfe ich, ob der User das Bild auf den Server geladen hat, welches zum Eintrag gehört und angegeben ist
 
@Bild:
Ja schon, aber: das machst du ganz unten noch einmal. Du referenzierst keine Variable in dem Quellcode irgendwo noch einmal.

@CSV:
Na ja, wenn ich das richtig sehe, dann muss der User ja gar nichts entscheiden, da die Namen der Spalten ja in der 4. Zeile schon stehen.
Dann könntest du die komplette Logik so machen, dass tatsächlich nur ein Upload nötig ist.

Ich hab mir den Code grad noch mal angeschaut, die Optimierung war viel zu lasch :) .
Code:
//Daten werden in csvanzeigen_[$_SESSION['userid']] geladen
$sql = "UPDATE nd_csvanzeigen_".$_SESSION['userid']." SET id=id";
$sqlend=" WHERE id='".$Zeilen."'";
for ($i = 0; $i < count($anzeige_normal); $i++)//Ignoriere alle Spalten, die nicht angegeben sind
{
 if ($anzeige_normal[$i] == "laufzeit")
 {
  $gueltig = $Daten[$i] * 86400;
  $sql .= ",gueltig='".($cfg['time'] + $gueltig)."'";
 }
 elseif ($anzeige_normal[$i] == "start_preis")
 {
  $start_preis = str_replace(",", ".", $Daten[$i]);
  $sql .= ",start_preis='".$start_preis."'";
 }
 elseif ($anzeige_normal[$i] == "mindestpreis")
 {
  $mindestpreis = str_replace(",", ".", $Daten[$i]);
  $sql .= ",mindestpreis='".$mindestpreis."'";
 }
 elseif ($anzeige_normal[$i] == "sofort_preis")
 {
  $sofort_preis = str_replace(",", ".", $Daten[$i]);
  $sql .= ",sofort_preis='".$sofort_preis."'";
 }
 elseif ($anzeige_normal[$i] == "versand_preis")
 {
  $versand_preis = str_replace(",", ".", $Daten[$i]);
  $sql .= ",versand_preis='".$versand_preis."'";
 }
 elseif ($anzeige_normal[$i] == "beschreibung" && $config['html_editor'] == "ja")
 {
  $Daten[$i] = nl2br($Daten[$i]);
  $sql .= ",beschreibung='".$Daten[$i]."'";
 }
 elseif ($anzeige_normal[$i] == "bild" && $Daten[$i] != '' && file_exists("member/csvupload/".$_SESSION['userid']."_".$_SESSION['username']."/".$Daten[$i].""))
 {
  $sql = "UPDATE nd_csvbilder_".$_SESSION['userid']." SET bild1='".$Daten[$i]."' WHERE anzid='".$Zeilen."'";
  mysql_query($sql, $db);
  $sql .= ",bild_anzahl='1'";
 }
}
mysql_query($sql.$sqlend, $db);
Eigentlich sollte das jetzt direkt funktionieren, ohne dass du den User irgendwas entscheiden lassen müsstest.

Ne Anmerkung: Dein Code ist offen wie ein Scheunentor und es ist eigentlich nicht Sinn und Zweck, dass man Nutzer in Tabellen separiert (man macht eine Spalte user_id REFERENCES(users.id) ON DELETE CASCASE ON UPDATE CASCADE, dann hat man deutlich weniger Tabellen. (Ab ca. 10000 Tabellen wird es nämlich spürbarer langsam, da du auf Tabellen(namen) keine Indizes setzten kannst.
 
Hancock schrieb:
@Bild:
Ja schon, aber: das machst du ganz unten noch einmal. Du referenzierst keine Variable in dem Quellcode irgendwo noch einmal.

@CSV:
Na ja, wenn ich das richtig sehe, dann muss der User ja gar nichts entscheiden, da die Namen der Spalten ja in der 4. Zeile schon stehen.
Dann könntest du die komplette Logik so machen, dass tatsächlich nur ein Upload nötig ist.

Ich hab mir den Code grad noch mal angeschaut, die Optimierung war viel zu lasch :) .
Code:
//Daten werden in csvanzeigen_[$_SESSION['userid']] geladen
$sql = "UPDATE nd_csvanzeigen_".$_SESSION['userid']." SET id=id";
$sqlend=" WHERE id='".$Zeilen."'";
for ($i = 0; $i < count($anzeige_normal); $i++)//Ignoriere alle Spalten, die nicht angegeben sind
{
 if ($anzeige_normal[$i] == "laufzeit")
 {
  $gueltig = $Daten[$i] * 86400;
  $sql .= ",gueltig='".($cfg['time'] + $gueltig)."'";
 }
 elseif ($anzeige_normal[$i] == "start_preis")
 {
  $start_preis = str_replace(",", ".", $Daten[$i]);
  $sql .= ",start_preis='".$start_preis."'";
 }
 elseif ($anzeige_normal[$i] == "mindestpreis")
 {
  $mindestpreis = str_replace(",", ".", $Daten[$i]);
  $sql .= ",mindestpreis='".$mindestpreis."'";
 }
 elseif ($anzeige_normal[$i] == "sofort_preis")
 {
  $sofort_preis = str_replace(",", ".", $Daten[$i]);
  $sql .= ",sofort_preis='".$sofort_preis."'";
 }
 elseif ($anzeige_normal[$i] == "versand_preis")
 {
  $versand_preis = str_replace(",", ".", $Daten[$i]);
  $sql .= ",versand_preis='".$versand_preis."'";
 }
 elseif ($anzeige_normal[$i] == "beschreibung" && $config['html_editor'] == "ja")
 {
  $Daten[$i] = nl2br($Daten[$i]);
  $sql .= ",beschreibung='".$Daten[$i]."'";
 }
 elseif ($anzeige_normal[$i] == "bild" && $Daten[$i] != '' && file_exists("member/csvupload/".$_SESSION['userid']."_".$_SESSION['username']."/".$Daten[$i].""))
 {
  $sql = "UPDATE nd_csvbilder_".$_SESSION['userid']." SET bild1='".$Daten[$i]."' WHERE anzid='".$Zeilen."'";
  mysql_query($sql, $db);
  $sql .= ",bild_anzahl='1'";
 }
}
mysql_query($sql.$sqlend, $db);
Eigentlich sollte das jetzt direkt funktionieren, ohne dass du den User irgendwas entscheiden lassen müsstest.

Ne Anmerkung: Dein Code ist offen wie ein Scheunentor und es ist eigentlich nicht Sinn und Zweck, dass man Nutzer in Tabellen separiert (man macht eine Spalte user_id REFERENCES(users.id) ON DELETE CASCASE ON UPDATE CASCADE, dann hat man deutlich weniger Tabellen. (Ab ca. 10000 Tabellen wird es nämlich spürbarer langsam, da du auf Tabellen(namen) keine Indizes setzten kannst.

Hallo Hancock,

danke Dir.
Es ist schon richtig, dass es jetzt schon funktioniert, das Problem ist nur das ich es so nicht mehr haben möchte. Denn auf diese Weise muss ich dem User vorschreiben, wie seine csv Datei aufgebaut sein muss.
Aus diesem Grund möchte ich es doch umschreiben, damit der User eine beliebige Datei hochladen kann und diese dann entsprechend zuweisen kann.
 
OK, jetzt versteh ich, was dein Problem ist.
Du willst dem Kunden quasi völlig frei stellen, wie seine CSV auszusehen hat.

Dann zwing ihn, dass er dir keinen "Header" rein macht. (Das kannst du via <Input> klären).


Code:
<?php
$anzeige_normal=array('a','b','c','d');//MySQL-Spaltennamenif(!isset($_POST["do_upload"){
 ?>
 <form method="post" enctype="multipart/x-form-data"><!-- ist der enctype richtig?-->
 <input type="hidden" name="do_upload" value="<?php echo microtime(true);?>">
 <input type="file" name="file">
 ...input quote input delim input whatever input submit
 </form>
 <?php }
else{
 $pid=$_POST["do_upload"];
 $_SESSION[$pid]=array(
  "file"=>move_to_storage($_FILE["file"]["tmp_path"]),//sicherlich ein Typo drin
  "delim"=>$_POST["delim"],
  "quote"=>$_POST["quote"]
  );
 
 
 $f=fopen($_FILE["file"]["tmp_path"],"rb");
 $first=fgetcsv($f,1<<16,$_POST["delim"],$_POST["quote"]);
 ?><form method="post"><input type="hidden" name="id" value="<?php echo $pid;?>"><?php 
 foreach($anzeige_normal as $val){
  echo $val."<select name=\"".$val."\">";
  foreach($first as $index=>$i){
   echo "<option value=\"$index\"".($i==$val?" selected=\"selected\"":"").">$i</option>";
  }
  echo "</select>";
 }
 echo "input submit</form>";
}
if(isset($_POST["id"])){
 $datei=$_SESSION[$_POST["id"]]["file"];
 $Dateizeiger = fopen("member/csvupload/".$_SESSION['userid']."_".$_SESSION['username']."/".$datei."", "r");
 $anzeige_normal = $_SESSION[$_POST["id"]]["anzeige_normal"];
 fgetcsv($Dateizeiger, 100000, ";");//erste Zeile => uninteressant
 for($Zeilen=1;($Daten = fgetcsv($Dateizeiger, 100000, ";"))!==false;$Zeilen++)
 {
  $query = "INSERT into nd_csvanzeigen_".$_SESSION['userid']." (id) values ('$Zeilen')";
  mysql_query($query, $db);
  $query = "INSERT into nd_csvbilder_".$_SESSION['userid']." (anzid) values ('$Zeilen')";
  mysql_query($query, $db);
  //Daten werden in csvanzeigen_[$_SESSION['userid']] geladen
  $sql = "UPDATE nd_csvanzeigen_".$_SESSION['userid']." SET id=id";
  $sqlend=" WHERE id='".$Zeilen."'";
  for ($i = 0; $i < count($anzeige_normal); $i++)//Ignoriere alle Spalten, die nicht angegeben sind
  {
   if ($anzeige_normal[$i] == "bild" && $Daten[$_POST[$anzeige_normal]] != '' && file_exists("member/csvupload/".$_SESSION['userid']."_".$_SESSION['username']."/".$Daten[$i].""))
   {
    $sqlb = "UPDATE nd_csvbilder_".$_SESSION['userid']." SET bild1='".$Daten[$_POST[$anzeige_normal]]."' WHERE anzid='".$Zeilen."'";
    mysql_query($sqlb, $db);
    $sql .= ",bild_anzahl='1'";
   }
   else
   $sql .= ",{$anzeige_normal}={$Daten[$_POST[$anzeige_normal]]}";
  }
  mysql_query($sql.$sqlend, $db);
 }
}

Mal so als grobes Grundgerüst. behebt dir die Sicherheitslücken und die Desingprobleme natürlich nicht vollständig.
 

Ähnliche Themen

Zurück
Oben