Doubletten in CSV verhindern
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
abteilung
array
bauen
beispiel
code
datei
datum
eingabe
file
formular
funktion
header
kopf
spalte
spalten
speichern
string
vorhanden code
vorname
zeile
-
Hallo
ich will per PHP eine einfache CSV Datei schreiben (pflegen: edit / new / delete)
vereinfachte Beispiel-Daten: CSV-Datei mit Kopf-Zeile (= Spalten-Namen) und 3 Daten-Zeilen
"vorname";"name","abteilung" "Tina";"Toll";"Personal" "Host";"Holle";"Einkauf" "Bernd";"Brot";"Marketing"
über eine Formular kann man neue Einträge erstellen. ($_POST ---> fwrite() in die CSV)
<?php // ------------------------------------------------------------- // --- Speichern in CSV bei neuer Datensatz --- if ( !empty($_POST['vorname']) && !empty($_POST['name']) && !empty($_POST['abteilung']) ) { $save_vorname = trim(chop($_POST['vorname'])); $save_name = trim(chop($_POST['name'])); $save_abteilung = trim(chop($_POST['abteilung'])); // --- ??? ... hier prüfen, ob vorname und name schon eingetragen sind ... ??? // --- und nur Speichern, wenn NEIN (noch nicht drin) ... sonst Meldung $save_file = 'data/mitarbeiter1.csv'; $kopf_zeile = '"vorname";"name";"abteilung"'."\n"; $datenzeile = '"'.$save_vorname.'";"'.$save_name.'";"'.$save_abteilung.'"'."\n"; if (!file_exists($save_file)) { $handle1 = fopen($save_file, 'w', 0666); // ---- neue Datei 'w"' erstellen ---- fwrite($handle1,$kopf_zeile); // ---- neue Kopf-Zeile schreiben ---- fwrite($handle1,$datenzeile); // ---- neue Daten-Zeile schreiben ---- fclose($handle1); } else { $handle1 = fopen($save_file, 'a', 0666); // ---- in Datei 'a' dazu schreiben---- fwrite($handle1,$datenzeile); // ---- neue Daten-Zeile schreiben ---- fclose($handle1); } print "<p>OK ... die Daten wurden gespeichert.</p>\n"; } else { // ------------------------------------------------------------- // --- Formular zur Eingabe neuer Datensatz --- $formulat1 = ' <form name="form1" method="post" action=""> Vorname: <input type="text" name="vorname" size="30" maxlength="60" /> <br /> Nachname: <input type="text" name="name" size="30" maxlength="60" /> <br /> Abteilung: <input type="text" name="abteilung" size="30" maxlength="100" /> <br /> <br /> OK: <input type="submit" name="go" value="Speichern" /> </form> '; print $formulat1; } // ------------------------------------------------------------- ?>
Wie kann ich verhindern, dass eine Person / ein voller Name (= vorname + name)
nicht doppelt eingetragen werden kann,
also wenn jemand in die Beispiel-Daten (oben) nochmal "Tina Toll" eintragen will,
dass dann eine (Fehler-) Meldung kommt wie z.B: "Der Name ist bereits eingetragen."
was ist besser,
+ die CSV als Array einlesen (fgetcsv) und dann Eingabe mit Array-Elemente vergleichen,
+ oder die CSV als "String" durchsuchen nach Teilstring (Zeichenkette) :"Tina";"Toll";
Das Vorkommen einzelner Zeichen suchen / finden kann man ja mit strpos()
... aber geht das auch mit einem Teilstring (Zeichenkette) ?
Oder ist es mit Array besser (schneller) ... oder hat jemand noch ne andere Idee ?
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Ich bin ein Fan von Arrays, string wär zwar schneller, aber über arrays kannst du schneller auf fehler abprüfen, wobei sich das mit den strings ncihts nimmt, wenn man sich darüber mehr gedanken macht.
du musst schauen, was passiert, wenn exotische Zeichen auftreten, welcher Befehl kann zum beispiel mit nicht ascii-konformen zeichen umgehen(wo dann UTF-8 erforderlich wird). fgetcsv kannt ich bisher nicht, ich habe files immer zielenweise(fgets) angelegt und meine eigene Struktur in einer schleife den Inhalt aufnehmen lassen...
das würde es dir auch leichter machen, es in andere programmiersprachen zu portieren... falls du das als eigene exe mit C++ bauen willst zum beispiel... -
ok, ich glaub ich habe meine csv_to_array Funktion so umgebaut,
damit es auch Array je einzele Spalte liefern kann ...
Wenn man Parameter $node als Leerstring (oder null oder false) angibt,
dann wird die komplette CSV in Array umgewandelt (mit allen Spalten)
Wenn man als Parameter $node einen Spalten-Name übergibt,
dann bekommt man ein einfaches (ein-dimensionales) Array
mit nur den Werten aus dieser einen Spalte
wenn ohne Kopf-Zeile ($head=false), dann als $node Spalten-ID mit 1 beginnen,
nicht mit 0 (Null) weil wenn $node=0 dann gilt $node bei empty() als 'leer'
... habe es aber noch nicht mit CSV ohne Kopfzeile ausprobiert ... :oO
<?php // ------------------------------------------------------------------- function csv_to_array($file,$node='',$head=true,$delim=';',$len=0) { $return = false; $handle = fopen($file, "r"); if ($head) { $header = fgetcsv($handle, $len, $delim); } $i=1; while (($data = fgetcsv($handle, $len, $delim)) !== FALSE) { if ($head AND isset($header)) { foreach ($header as $key => $heading) { if (!empty($node)) { if ( $heading == $node ) { $row = (isset($data[$key])) ? $data[$key] : ''; } } else { $row[$heading] = (isset($data[$key])) ? $data[$key] : ''; } } $return[] = $row; } else { if (!empty($node)) { if ( $node == $i ) { $return[] = $data[$i]; } } else { $return[] = $data; } } $i++; } fclose($handle); return $return; } // ------------------------------------------------------------------- ?>
Dann kann ich für je nur eine Spalte einzeln ein Array raus holen
und prüfen, ob der Wert aus Eingabe als Wert (nicht) im Array vorkommt.
$varray = csv_to_array($save_file, 'vorname'); if ( !in_array($save_vorname , $varray) ) { // --- OK ... der Vorname ist noch nicht in den Daten } else { // --- STOP ... der Vorname ist bereits vorhanden }
Das funktioniert aber nur für eine Spalte, also entweder 'vorname' oder 'name'
ok, ... Ich zwar kann auch beide Spalten so prüfen
$varray = csv_to_array($save_file, 'vorname'); $narray = csv_to_array($save_file, 'name'); if ( !in_array($save_vorname , $varray) && !in_array($save_name, $narray) ) { // ...... ok ... } else { // ..... nicht speichern ... schon vorhanden ... }
aber dann würde auch "Tina Holle" oder "Bernd Toll" fälschlicher Weise als Doublette erkannt,
also muss ich wohl die zwei Spalten zu einem String zusammen bauen und diesen dann prüfen
$varray = csv_to_array($save_file, 'vorname'); $narray = csv_to_array($save_file, 'name'); $xarray = array(); $anzahl = count($varray); for ($x=0; $x<$anzahl; $x++) { $xarray[] = $varray[$x].'_'.$narray[$x]; } $checkstring = $save_vorname.'_'.$save_name; if ( !in_array($checkstring, $xarray) ) { // ...... ok ... } else { // ..... nicht speichern ... schon vorhanden ... }
das macht die Sache aber ganz schön kompliziert,
aber wahrscheinlich immernoch einfacher, als die Funktion so um zu bauen,
dass die auch mit mehreren $node arbeiten kann und ein Array mit $checkstring je Zeile zurück gibt
welches man dann mit dem $checkstring aus der Formular-Eingabe vergleichen kann (in_array)
... wie gesagt, die Beispiel-Daten hier sind stark vereinfacht,
bei den echten Daten gibt es auch andere Spalten-Kombinationen,
die nicht "doppelt" gespeichert werden dürfen, z.B. Telefon-Nr, etc.
PS: ein Umbau von fgetcsv() zu fgets() und Zeile splitten wäre denke ich schon machbar
bzw. man kann sich für C++ etc. dann ja einen eigene fgetcsv() Funktion selber machen
wenn die nicht als Basis-Funktion enthalten ist wie bei PHP ...
... aber da ich es sowieso erstmal nur im Web brauche, ist PHP fgetcsv ja verfügbar.
-
Warum machst du aus dem Array, was du aus fgetcsv bekommst net einfach mittels implode nen String und schaust mit strstr oder so, ob der Name schon vorhanden ist?
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage