Trotz was?
Von dem foreach hat doch keiner was gesagt.
Wie gesagt; Den eigenen Code lesbar im Forum präsentieren
Beiträge von cottton
-
-
Guck mal bitte hier: Den eigenen Code lesbar im Forum präsentieren
Weiß nicht genau, was Du vorhast, aber in dem Bild ist wohl das <li> nicht geschlossen.
-
Nein nein, ich meinte, dass Du im Script besser und übersichtlicher unterscheiden kannst, welche Form gerade rein kommt.
In etwa:PHPif (isset($_POST['hiddenfield_form_1'])) { // hier alles um die eingaben für form "eins" zu behandeln } elseif (isset($_POST['hiddenfield_form_2'])) { // hier alles um die eingaben für form "zwei" zu behandeln } else { // keine der beiden wurde abgesandt }An XAMPP liegt das glaub ich nicht.
Es ist evtl ein Schusselfehler, vtl was simples, was man aber bei der "Kompaktheit" nicht sieht =)Kurze Namen/Keys und alles auf einer Zeile ist schlecht, gerade beim Fehler finden.
Besser ist immer aussagekräftige Namen zu nutzen.Wenn es um die URL geht, dann kann man ja Kürzel nutzen. Also Besser "uname" statt "user_name" oder "something_too_long_for_the_url".
Dann sollte man aber im PHP Code mit aussagekräftigen Variablen arbeiten, wie zB:PHP// HTML imput feld heißt zB name="tm_datum" $terminDatum = isset($_POST['tm_datum']) ? $_POST['tm_datum'] : null;
Hier am Bsp siehst Du sofort, welches Feld erwartet wird, und was damit passiert (weil auf 3 Zeilen - meiner Meinung nach übersichtlich) -
Das "Problem" ist die config, die Du beim Verbinden mit gibst.
Info dazu zB hier: https://www.php-einfach.de/2015/08/emulie…ulate_prepares/Durch diese Einstellung überlässt Du dem DB-Server das parsen der Platzhalter.
Und der kommt mit mehreren gleichen nicht klar (will nicht, kann nicht , oder soll evtl auch nicht).PDO::ATTR_EMULATE_PREPARES In kurz:
Wenn false, dann wird die Query nicht von PHP ge-parsed, sondern Query und Values an den DB-Server gesandt.
Der kümmert sich dann um die Query/Platzhalter/Values.
Wenn true, dann übernimmt PHP (PDO) das parsen (emuliert). Der DB-Server bekommt dann die "fertige" Query, ohne Platzhalter.Zur Sicherheit: in der Theorie sollte man meinen, dass ein Extra Layer (Schicht), der die Query behandelt, "extra" anfällig wäre.
Da sich aber immer nur einer um die Platzhalter kümmert (entweder PHP order DB-Server), stellt sich eher die Frage
"Wer ist vertrauenswürdiger?".
Behandelt also PHP oder der DB-Server die Platzhalter besser.
Da könnte man sich streiten.
Man könnte meinen, wenn man immer PHP emulieren lässt, dann bekommt man auch immer das gleich sichere Ergebnis,
egal welcher DB-Server gerade genutzt wird.
(Das könnte man per Pro und Contra noch weiter ausführen. Dabei kommen aber noch Versionen ect dazu und das Thema endet nie)Empfehlen würde ich Default - also true (gar nicht erst in der config mitgeben). Aber das ist meine persönliche Meinung.
BTW: PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION würde ich empfehlen. Fehler sind übersichtlicher, beinhalten mehr Informationen und können einfacher abgefangen werden.
Es sieht zwar umständlich aus, immer einen try/catch -Block um alle Statements (prepare, execute) zu setzen,
aber man spart sich das unterschiedliche Abfangen bei PDO::prepare und PDOStatement::execute.
(Wobei bei ::prepare selten ein Fehler auftreten sollte. Das passiert dann eher bei ::execute)
Und man bekommt per $e->getMessage() die schon fertige, lesbare Meldung. Per ::errorInfo muss man sich die Message selbst zusammen schneidern.So, war wieder viel, hab aber selbst noch was dabei gelernt

-
Ach Du hast ja eingestellt, dass Du objects bekommst.
Dann muss es heissen $row->count_benutzername usw.Das mit dem ersten Fehler muss ich mir bei Gelegenheit mal ansehen.
Aber mit der "email2" Alternative sollte es funktionieren.
(man könnte es auch sinnvoller benennen =) -
Du hast vergessen die row zu ziehen:
PHP$stmt_uberprufung = .. $stmt_uberprufung->execute ... $row = $stmt_uberprufung->fetch(); // zieht eine row, und wir erwarten nur eine if($row['count_benutzername'] > 0){ // benutzername schon vergeben } if($row['count_email'] > 0){ // email schon vergeben }Die Fehlermeldung sagt, dass Anzahl Platzhalter und Anzahl der übergebenen Platzhalter => Werte nicht übereinstimmt.
Das sollte aber so funktionieren. Denn 2 x :email braucht nur 1 x array('email' => $email).Anders geht die Query immer. Aber ich denke diese macht am meisten Sinn.
Durch die WHER Bedingung werden alle rows gesucht, die benutzername oder email besitzen.
Und dann wird aus diesen rows die counts erstellt.
Bei UNIQUE benutzername und email sollte das max 2 rows sein, welche (wenn ich mich nicht irre) 4 x COUNT() ausführen.
Die IFs sind schon kurz: WENN, DANN, SONST. Und die müssen sein, damit COUNT() nicht mitzählt, wenn benutzername oder email nicht gleich den gesuchten Wert enthält.Wenn Du immernoch die Fehlermeldung bekommst, dann versuche mal das:
PHP
Alles anzeigen$stmt_uberprufung = $pdo->prepare("SELECT COUNT(IF(`benutzername` = :benutzername2, 1, NULL)) AS `count_benutzername`, COUNT(IF(`email` = :email2, 1, NULL)) AS `count_email` FROM `Registrierdaten`WHERE `benutzername` = :benutzername OR `email` = :email;"); $result2 = $stmt_uberprufung->execute( array( ':benutzername' => $benutzername, ':benutzername2' => $benutzername, ':email' => $email, ':email2' => $email, ) ); if (!$result2) { $fehler[] = 'Fehler in der Datenbankabfrage!'; } else { $row = $stmt_uberprufung->fetch(); if ($row['count_benutzername'] > 0) { $fehler[] = '<p class="fehler">Der eingegebene Benutzername wird schon genutzt</p>'; } if ($row['count_email'] > 0) { $fehler[] = '<p class="fehler">Die eingegebene E-Mail-Adresse wird schon genutzt</p>'; } }
aber wie gesagt, eigtl sollte es ohne "sinnlose extraPlatzhalter" funktionieren. -
So langsam klingelts. Verstehe es nicht ganz, aber verstehe den Sinn hinter den "status" inputs.
Macht Sinn.Probiers mal mit hidden fields.
In jede Form ein
"staus" wäre hier die erste Form, denk ich.
Mit PHP kannst Du dann mit $_POST['form_submitted'] checken, welche Form abgesandt wurde. -
Dann kannst Du die Felder zählen lassen.
SQL
Alles anzeigenSELECT -- IF(WENN, DANN; SONST) -- COUNT(NULL) zählt nicht hoch -- AS setzt alias -- zählen, wie oft der benutzername vorkommt COUNT(IF(`benutzername` = :benutzername, 1, NULL)) AS `count_benutzername`, -- zählen, wie oft die email vorkommt COUNT(IF(`email` = :email, 1, NULL)) AS `count_email` FROM `Registrierdaten` WHERE `benutzername` = :benutzername OR `email` = :email ;
Bsp Ergebnis
Ich hatte testweise mal nen Table angelegt mit 3 x dem gesuchten Benutzernamen, und 2 mal der gesuchten Email.
(email und benutzername sollten allerdings immer nur einmal vorkommen - siehe UNIQUE index Post oben)In PHP (In $result) prüfst Du dann, ob
email > 0 (dann email schon vergeben)
benutzername > 0 (benutzername schon vergeben).Du solltest immer exact 1 row bekommen. Wenn email und benutzername in der tabelle nicht vokommen,
dann gibts 1 row mit den Werten 0 und 0. -
Wenn die 2 Checkboxen nach Browserrefresh angekreuzt sind, und default nicht,
dann ist die Eingabe per PHP oder JS "gespeichert".
Man müsste also wissen, wie/von wem die Boxen wieder angehakt werden.Ohne Code geht da nix. Raten bringt nix =)
-
Das Rot und Grün - die Farben sind so "dick". Das lässt es plump aussehen.
Sonst ok. Nav usw scheint ja alles zu funktionieren. -
Yap, da stimmt einiges nicht:
HTML
Alles anzeigen<section id="daten"> <form method="POST" name="status"> <section id="status"> <input type="image" src="../standard/icon/icon_anzeigen_bla.png" title="anzeigen/display" value="anz" class="button" name="status" <!-- "anz" ? --> > <img src="../standard/icon/icon_suchen_gra.png" title="suchen/search" value="suc" <!-- attribute "value" is not allowed here --> class="button_gr" name="status" <!-- "suc" ? --> > <input type="image" src="../standard/icon/icon_bearbeiten_bla.png" title="bearbeiten/change" value="bea" class="button" name="status" <!-- "bea" ? --> > <input type="image" src="../standard/icon/icon_neu_gru.png" title="neu/new" class="button" value="neu" name="status" <!-- "neu" ? --> > <input type="image" src="../standard/icon/icon_sichern_rot.png" title="sichern/save" value="sic_neu" class="button" name="status" <!-- "sic_neu" ? --> > <img src="../standard/icon/icon_loeschen_gra.png" title="löschen/delete" value="loe" <!-- attribute "value" is not allowed here --> class="button_gr" name="status" <!-- "button_gr" ? --> > </section> <hr> </form> <form method="POST" name="daten_detail"> <h2>NEU</h2> <table id="person"> <tbody> <tr> <td><h3>NEUEN TERMIN <br> ANLEGEN</h3></td> </tr> <tr> <td class="feldname">Datum von:</td> <td><input type="date" name="tm_datum_von" class="feldinhalt" value=""></td> </tr> <tr> <td class="feldname">Datum bis:</td> <td><input type="date" name="tm_datum_bis" class="feldinhalt" value=""></td> </tr> <tr> <td class="feldname">Stichwort:</td> <td><input type="text" name="tm_stichwort" class="feldinhalt" value=""></td> </tr> <tr> <td class="feldname">Beschreibung:</td> <td><textarea rows="20" col="70" name="tm_beschreibung" class="feldinhalt" value=""></textarea></td> <!-- textarea: attribute "value" is not allowed here --> <!-- textarea: attribute "col" is not allowed here --> </tr> <tr> <td><input type="submit" class="button_link"></td> </tr> </tbody> </table> </form> <pre>Array ( [status_x] => 8 [status_y] => 24 [status] => neu [tm_datum_von] => [tm_datum_bis] => [tm_stichwort] => [tm_beschreibung] => ) </pre> </section> -
In Deinem ursprünglichen Post DB PDO Wert aus Datenbank mit variable vergleichen
hast Du den Benutzer eingefügt (INSERT INTO), und dann geprüft, ob er existiert
Das hier (ungetestet) sollte funktionieren
PHP
Alles anzeigentry { //$pdo = new PDO('mysql:host=localhost; <-------------------------------- WASN HIER LOS oO? (absatz im string =) // dbname=apple231', //der Host und dbname $pdo = new PDO('mysql:host=localhost;dbname=apple231', //der Host und dbname '**', // User-Name '***', //Password array( PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ, // gibt an, dass man die Rückgabe eines Datensatzes von Methoden als Objekt erhaltet PDO::ATTR_EMULATE_PREPARES => false, // sagt, dass man nicht nur emulieren wollen, sondern PreparedStatements nutzen wollen PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION // PDO veranlassen , Exceptions zu werfen, die man abfangt und darauf reagiert ) ); } catch (Exception $e) { exit('Fehler beim verbinden:' . $e->getMessage()); } try { // INFO: // auf dem table `Registrierdaten` sollten unique indexes vergeben werden: // UNIQUE INDEX `uidx_email` (`email`) -- unique email // UNIQUE INDEX `uidx_benutzername` (`benutzername`) -- unique benutzername // UNIQUE INDEX `uidx_email_benutzername` (`email`, `benutzername`) -- unique email/benutzername -combi $stmt_uberprufung = $pdo->prepare( "SELECT `id` FROM `Registrierdaten` WHERE `benutzername` = :benutzername OR `email` = :email ;" // SELECT `id` -- mehr brauchen wir nicht, um festzustellen, dass es den user schon gibt // WHERE `benutzername` = :benutzername AND `email` = :email -- user kann sich mit email und benutzernamen mehrmals anmelden // WHERE `benutzername` = :benutzername OR `email` = :email -- benutzername oder email schon vergeben ); $stmt_uberprufung->execute( array( ':benutzername' => $benutzername, ':email' => $email ) ); if (!$result) { $fehler[] = 'Fehler in der Datenbankabfrage!'; } else { if ($stmt_uberprufung->rowCount() > 0) { $fehler[] = '<p class="fehler">Der eingegeben Benutzername wird schon genutzt</p>'; } else { // wir können den benutzer anlegen $statement = $pdo->prepare( "INSERT INTO `Registrierdaten` (`vorname`, `nachname`, `email`, `tag`, `monat`, `jahr`, `benutzername`, `password`, `hashid`) VALUES(:vorname, :nachname, :email, :tag, :monat, :jahr, :benutzername, :password, :hashid) ON DUPLICATE KEY UPDATE `id` = `id` ;" ); // "ON DUPLICATE KEY UPDATE `id` = `id`" bewirkt, dass wir keinen fehler beim einfügen eines duplikates bekommen // (wenn zB email und/oder benutzername UNIQUE INDEX ist), // sondern "nichts" unternehmnen (UPDATE `id` = `id` bewirkt keine änderung am datensatz - löst auch keine TRIGGER aus (teilweise getestet) ) // // ist nicht wirklich nötig, wenn wir sowieso prüfen, ob der user schon existiert, // ist aber fehlerunanfälliger. $result = $statement->execute( array( ':vorname' => $vorname, ':nachname' => $nachname, ':email' => $email, ':tag' => $tag, ':monat' => $monat, ':jahr' => $jahr, ':benutzername' => $benutzername, ':password' => $password_gehahst, ':hashid' => $hashid_email, ) ); if (!$result) { var_dump($statement->errorInfo()); } } } } catch (Exception $a) { echo 'Ein Fehler ist aufgetreten : (' . $a->getCode() . ') ' . $a->getMessage(); exit; } -
Ich sehe Du hast da Images als Submit Button, oder?
hab keine Ahnung, wie die reagieren. Evtl ist das das Problem?Probier mal mit nomalen "submit" Buttons
EDIT: lass Dir mal vom Browser den Quellcode anzeigen (wenn Seite neu aufgebaut ist - ohne Dateneingabe)
und poste den HTML code mal.
Oft sieht man dann eherwo der Fehler steck. -
Ich sehe keinen Submit Button oO?
Das Problem verstehe ich auch nicht.Aber btw:
Du schreibst oft NULL in den "leeren Raum".PHP//Bsp empty($_POST['tm_datum_von']) ? $_POST['tm_datum_von'] = "" : NULL; // oder case 'no' : NULL; break;
Weiß nicht mehr, wie man das nannte, ist aber nicht empfohlen.
Besser wäre:PHP//wenn es kurz sein muss empty($_POST['tm_datum_von']) and $_POST['tm_datum_von'] = ""; // oder !empty($_POST['tm_datum_von']) or $_POST['tm_datum_von'] = ""; // und case 'no' : break;
EDIT:
wobei empty hier wieder unerwünschte Ergebnisse bringen kann!
0, '0', NULL, '', array(), und einiges mehr sindt empty.
Würde das hier empfehlen:
Und dann die var weiterhin nutzen.
/EDITWas das Ganze hier schwirig macht, ist, dass Du HTML und PHP so sehr vermischst.
Du schreibst auch IF Bedingungen in eine Zeile. Wer soll das lesen? =)Funktion:
PHPstatus_detail($anz='gru',$suc='bla',$bea='bla',$neu='bla',$sic_bea='gra',$sic_neu='no',$loe='rot');
Du musst nicht die Variablen setzen, wenn Du sie später nicht benötigst.
Die Werte in die Funktion zu schicken reicht völlig aus:
Und wenn es mal viele Parameter sind, sollte man ein Array übergeben:PHP$params = array( 'gru', // anz 'bla', // suc 'bla', // bea 'bla', // neu 'gra', // sic_bea 'no', // sic_neu 'rot', // loe ); status_detail($params);Evtl liegt hier der(?) Fehler:
Siehe KommentarePHPecho "<td> <input type="date" name="tm_datum_von" class="feldinhalt" value="".clearstring($_POST['tm_datum_von']).""></td></tr>"; // echo " -- startet den String // <td> <input type="date" -- kaputt! " muss maskiert werden
Besser:PHPecho '<td> <input type="date" name="tm_datum_von" class="feldinhalt" value="' . clearstring($_POST['tm_datum_von']) . '"></td></tr>';
Ich sage (mir) immer: PHP string immer mit einfachen Anführungszeichen. HTML und JS und SQL mit doppelten. -
Sobald Du mit JS die Form ansprechen willst, kann der Name nützlich sein.
Für HTML -> PHP wüsste ich auch keinen Grund.
Aber der name -Tag ist ja schnell geschriebene, also macht man ja nix falsch, wenn man den Dingern nen Namen gibt =) -
Die Platzhalter stellen (logisch) den Platzhalter für die Werte dar,
die an dieser Stelle eingefügt werden sollen.
Damit stellst Du sicher, dass keine SQL-Injections möglich sind.
Siehe: http://php.net/manual/de/pdo.prepared-statements.phpZitatDie Parameter für Prepared Statements müssen nicht maskiert werden. Der Treiber übernimmt das automatisch.
Wenn eine Anwendung ausschließlich Prepared Statements benutzt, kann sich der Entwickler sicher sein, dass keine SQL-Injection auftreten wird.Der Benutzer kann also eingeben, was er will. Der Wert wird immer als (default) String in die Query eingefügt,
oder als den Typ, den man angegeben hat (PDO::PARAM_INT, ...).Die Fragezeichenplatzhalter sind Geschmackssache.
Ich mag die nicht. Die benanten Platzhalter (:name, :id, :usw) sind meiner Meinung nach übersichlicher.
Beide erfüllen aber den Zweck.(Jetzt nicht verwirren lassen)
Es gibt verschiedene Wege.
Zb Dein Weg mit Fragezeichen und ::bindParam,
oder :platzhalter und ::bidParam
oder :platzhalter und die Übergabe eines Arrays der Werte (siehe: http://php.net/manual/de/pdo.…repare-examples)Letzteres ist meiner Meinung nach das einfachste. Weniger Code, übersichtlicher (...).
Dein Bsp mit der (ich nenn es mal) Array-Variante:
PHP// SQL und params vorbereiten (als variablen nur zur übersicht im bsp) $sql = 'SELECT `hashid` FROM `Registriergang` WHERE `email` = :email;'; $params = array( ':email' => $_POST['email'] ); $stmt = $pdo->prepare($sql); // sql vorbereiten $stmt->execute($params); // execute die parameter für die platzhalter mit geben // und nun fetchAll oder der gewünschte weg, um die daten zu ziehenBei dem Bsp haben wir keinen Typ der Werte übergeben.
Das brauchen wir auch nicht, denn default wird immer ein PDO::PARAM_STRING eingefügt.
Dabei muss man aber bedenken, dass 1 als '1', 1.2 als '1.2' (...) eingefügt wird.
Das ist fast immer in Ordnung.
Der einzige Fall, in dem ich bisher den Typ mittels ::bindParam mitgeben musste ist,
wenn man eine LIMIT Query mit Platzhatern verwendet:Hier erwartet der Mysql Server Zahlen (integer).
Würden wir also keinen Typ angeben, würde PDO eine (zB) '2' einfügen, statt einer 2.Das heißt, dass wir einfach bei einem LIMIT die parameter binden (so wie in Deinem Bsp).
Welche Variante Du nutzt ist Dir überlassen.
###
Du hast en "Dreher" bei dem var_dump Bsp:
SQLSELECT `hashid` FROM `Registriergang` WHERE email = `stef@test.de` -- <- die `` gehören um email, und der wert wäre innerhalt der '' -- aber die '' um die werte übernimmt ja PDO für unsLässt sich relativ leicht merken:
Ist es ein Wert, dann '',
sosnt `` (Datenbank-, Tabellen-, und Spaltennamen)###
Zum try/catch
PHPtry { $stmt = $pdo->prepare('SELECT `hashid` FROM `Registriergang` WHERE email = ? '); // keine `` um das ?, dafür aber um `email` $stmt->bindParam(1, $email, PDO::PARAM_STR); $result = $stmt->execute(); } catch (Exception $e){ // einfach $e ist einfacher echo 'Ein Fehler ist aufgetreten : (' . $e->getCode() . ') ' . $e->getMessage(); // würde den code noch nutzen, der lässt sich oft gut googlen exit; }
Sollte so funktionieren. -
EDIT: ist kein Bug. War mein Fehler.
Kann das jemand bestätigen:
erstelle Datei - Bsp path/to/my/.hidden_one
und prüfe mit file_exists() ob diese Datei existiert:.

Gab mal 2001 nen Bugreport bei php.
Allerdings endete der Fall mit ~"einfache Anführungszeichen haben das Problem gelöst"
-- also file_exists('path/to/my/.hidden_one')
aber das bringt mir mit dem Pfad in ner var wenig
Thanks for helping!
cottton
Info:
ubuntu 14.04
PHP 7.0.8
Vergesst es -ist geklärt. War gestern spät/lang und ich hatte ein Problem mit der var (pfad Zusammenstellung). -
Sorry, war vorhin bissl in Eile, wollte den Post aber nicht nochmal schrieben und hab ihn angeschickt.
Was noch fehlte:
Der Wert, der in die Query geschrieben wird (per Variable $user),
der wird als Spaltenname (column) behandelt.
Am Bsp Deines letzen var_dump:
Es sollte so aussehen:Ein anderes Bsp:
angenommen in $user steckt der Wert name
dann wäre die Query
.
Was jetzt in dieser Query passiert ist:
- gib mir
- von Registrierdaten
- die hashid derer Datensätze
- bei welchen der benutzername GLEICH der name ist.Und das ist sicherlich nicht gewollt.
Außerdem will ich sehen, dass Du die Platzhalter verwendest
$ in Query is nich mehr. In dem String gehört nur noch :platzhalter (:user oder :benutzername oder :id oder was auch immer ...)
bei Fragen immer fragen
-
Verstehe ich immernoch nicht, was Du mit dem explode machst.
Also, dass dort der hash rein kommen soll - ok.
Aber den kannst Du doch per Name an die url hängen - wie zB
(oder hash oder h oder was auch immer der Name sein soll).Zur query:
Du hast es nicht, oder nicht rightig umgebaut.
Siehe comments:PHP
Alles anzeigen// deine query original: $statement = $pdo->prepare("SELECT hashid FROM Registrierdaten WHERE benutzername = ".$user." "); // zerlegt und fehler erklärt: $statement = $pdo->prepare( " SELECT hashid -- würde dir empfehlen die `` zu bei table names und columns zu nutzen - hier zB `hashid` FROM Registrierdaten -- hier auch - `Registrierdaten` WHERE benutzername -- hier auch `benutzername` = ".$user." " -- hier ist der fehler <------- -- angenommen $user hat den wert "cottton" -- dann erstellst du eine query: -- WHERE `benutzername` = cottton; -- beachte, dass cottton NICHT in '' anführungszeichen (für values immer) gesetzt sind. );
Es müsste also heißen:PHP$statement = $pdo->prepare("SELECT hashid FROM Registrierdaten WHERE benutzername = '".$user."' ");
Aber das ist immernoch falsch, denn Userinput gehört nicht direkt in die Query!
Also PLatzhalter verwenden!
Siehe http://php.net/manual/de/pdo.prepared-statements.php -