Beiträge von cottton

    Nein nein, ich meinte, dass Du im Script besser und übersichtlicher unterscheiden kannst, welche Form gerade rein kommt.
    In etwa:

    PHP
    if (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.

    PHP
    PDO::ATTR_EMULATE_PREPARES => false


    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 :)

    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:


    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

    HTML
    <input type="hidden" name="form_submitted" value="status">


    "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.


    Bsp Ergebnis

    Code
    # benutzername, email
    '3', '2'


    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.

    Yap, da stimmt einiges nicht:

    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 8|

    Das hier (ungetestet) sollte funktionieren

    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

    HTML
    <imput type="submit" ... name="..." ...

    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:

    PHP
    $tmDatumVon = isset($_POST['tm_datum_von']) ? $_POST['tm_datum_von'] : "";


    Und dann die var weiterhin nutzen.
    /EDIT

    Was 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:

    PHP
    status_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:

    PHP
    status_detail('gru', 'bla', 'bla', 'bla', 'gra', 'no','rot');


    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 Kommentare

    PHP
    echo        "<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:

    PHP
    echo '<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.php

    Zitat

    Die 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 ziehen

    Bei 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:

    PHP
    $sql = 'SELECT * FROM `tablename` WHERE `foo` = :foo LIMIT :skip, :limit;';

    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:

    SQL
    SELECT `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 uns

    Lässt sich relativ leicht merken:
    Ist es ein Wert, dann '',
    sosnt `` (Datenbank-, Tabellen-, und Spaltennamen)

    ###

    Zum try/catch

    PHP
    try
    {
        $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:

    PHP
    $file = 'path/to/my/.hidden_one';
    var_dump(file_exists($file));

    .
    ?(

    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 8|

    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:

    SQL
    SELECT hashid FROM Registrierdaten WHERE benutzername = stef1234 -- hier fehlen die ''


    Es sollte so aussehen:

    SQL
    SELECT hashid FROM Registrierdaten WHERE benutzername = 'stef1234'

    Ein anderes Bsp:
    angenommen in $user steckt der Wert name
    dann wäre die Query

    SQL
    SELECT hashid FROM Registrierdaten WHERE benutzername = name


    .
    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 :D
    $ 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

    Code
    www.url.de?activation=abc123....


    (oder hash oder h oder was auch immer der Name sein soll).

    Zur query:
    Du hast es nicht, oder nicht rightig umgebaut.
    Siehe comments:


    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