MYSQL suche mittels PDO

  • Hallo Leute,


    vielleicht kann mir hier jemand einen Rat geben, ich hab ein Search form geschrieben was bei submit die Suche an die search.php übergibt. Das geht auch alles super wenn ich nach der TrackingID Test1 suche dann wirft er mit den User aus, dem dies ID gehört.


    Jetzt folgendes, wenn ich die search.php einzeln im Browser aufrufe liest er halt alle User aus und zeigt alle an, wie kann ich das verhindern?



    Search form aus dem header.php

    Code
    <form action="search.php" method="post">
    <input type="text" name="search" placeholder=" ID"/>
    <input type="submit" value="suchen" />
    </form>
  • Jau danke,


    auch danke für den Hinweis, war im Testscript so um zu schauen ob es geht, hab's bereits geändert



    Code
    $query = $pdo->prepare("select trackingid, vorname, nachname, email from users where trackingid LIKE '%$search%' LIMIT 0 , 10");
  • Du müsstest eigtl. ein Fehler bekommen.

    Du bindest den Param `$search` aber schreibst ihn direct in die Query.


    KEINE VARS in die Query!


    SQL
    select * from users where trackingid LIKE :search LIMIT 0 ,10;
    
    -- oder
    
    select * from users where trackingid LIKE ? LIMIT 0 ,10;
  • LIKE :search funktioniert nicht, das andere geht aber es ging davor schon. Es erschließt sich mir nicht welche Vor- oder Nachteil es nun hat, da beides das gewünschte Ergebnis liefert


    Was ist denn jetzt der Unterschied zwischen

    LIKE ? LIMIT und LIKE '%$search%' LIMIT


    Ich würde es gerne verstehen




    und nur eine Nebenfrage, wenn ich das Ergebnis aus $results['email'] gleich als Empfänger in ein Contact Form einbinden will, geht das?

  • Code
    Ich würde es gerne verstehen

    Sehr gut!


    Man schreibt keine Variablen in die Query.

    Das sind Sicherheitslücken.

    Suche mal im Netz nach "SQL injections".


    Wenn Du Platzhalter (richtig) verwendest, dann ist eine SQL-Injection praktisch ausgeschlossen.


    Bsp:

    SQL
    SELECT * FROM `users` WHERE `trackingid` LIKE ?;

    ? ist hier ein Platzhalter.

    Bei der Ausführung übergibst Du dann die Values für die Platzhalter:

    PHP
    $stmt = $pdo->prepare("SELECT * FROM `users` WHERE `trackingid` LIKE ?;");
    $stmt->bindValue(1, "%{$search}%", PDO::PARAM_STR);
    $stmt->execute();

    Oder:

    PHP
    $stmt = $pdo->prepare("SELECT * FROM `users` WHERE `trackingid` LIKE :search;");
    $stmt->execute( 
        array(
            'search' => "%{$search}%"
            // die doppelpunkte muss man nicht mit angeben, kann man aber:
            // ':search' => "%{$search}%"
        )
    );
    // info: mit execute übergebene parameter werden immer als string eingefügt

    Siehe: http://php.net/manual/de/pdost…tatement.execute-examples



    Du hast es schon richtig gehabt, hast dann aber ::bindValue übergangen, in dem Du die Value direct in die Query geschrieben hast.

    Hätte von PHP eigtl einen Fehler erwartet - ~"number of parameters bound to ... does not match ...".




    Zur 2ten Frage:

    ALLE DATEN SIND BÖSE! <<--- merken =)

    $_POST, $_GET, aus Dateien, selbst in Deiner eigenen Datenbank ...

    alle Daten müssen als böse betrachtet werden.


    Bsp Browserausgabe:

    Alles mit (zB) htmlspecialchars() maskieren.

    PHP
    <?php
    // some code ...
    ?><div><?php echo htmlspecialchars($results['id']) ?></div>
    <div><?php echo htmlspecialchars($results['email']) ?></div>
    ?>
    // ...


    Mal angenommen ich hab beim Registrieren als email

    Code
    <script>alert('lulz');</script>

    angegeben. Und aus irgendeinem Grund ging das so in Deine db. (Oder jemand hatte zugriff auf die db ... wie auch immer...)

    Dann würde der Browser das hier bekommen:

    PHP
    <?php
    // some code ...
    ?><div>1</div>
    <div><script>alert('lulz');</script></div>
    ?>
    // ...

    ... und JS wird ausgeführt.



    ---

    Also:

    Alle Daten sind böse.

    SQL nie mit Variablen direkt füttern, sondern Platzhalter verwenden.

    HTML-Ausgaben immer mit zB htmlspecialchars() maskieren.

  • Ok super danke, dann sieht mein Code jetzt so aus; dazu habe ich noch eine Frage, ist das "if (isset($_POST['search']))" an der richtigen Stelle? Es wird zwar unterbunden, dass beim Aufrufen der search.php die ganze Datenbank angezeigt wird allerdings wenn man das Suchfeld leer lässt und auf suchen klickt, wird der ganze Inhalt der Datenbank angezeigt.


    Ich hab das jetzt mit einem simplen "required" im form unterbunden damit das nicht leer versendet werden kann aber das kann ja sicher nicht die Lösung dafür sein



  • Was scatello sagt oder gleich ne min-length bestimmen.

    Code
    $minLength = 3;
    if(isset($_POST['search']) and strlen($_POST['search']) >= $minLength){
    // ...
    }


    EDIT: und natürlich Leerzeichen am Anfang and Ende entfernen

    Code
    $minLength = 3;
    $search = '';
    if (isset($_POST['search'])) {
        $search = trim($_POST['search']);
    }
    
    if (strlen($search) >= $minLength) {
        // ... ab hier gehts weiter - aber nutze $search, nicht mehr $_POST['search']
    }
  • $minLength OK gut, das muss ich mir nochmal genauer durchlesen. Danke


    ich hätte jetzt in das form selbst noch zusätzlich das hier gehauen


  • Bei hochgedrehtem Error-Reporting wirft das

    Code
    if(!$error)

    eine Notice-Meldung raus, wenn $_POST['trackingid'] nicht leer ist, da diese Variable vorher nicht gesetzt ist. Aber wieso überhaupt diese Variable?

    Code
    if(empty($trackingid))
       echo 'Es ist keine ID enthalten<br>';
    else 
    {
       :
       :
       :
    }

    Außerdem wird dein geposteter Quellcode nicht funktionieren, denn hier

    Code
    if(empty($trackingid)

    fehlt eine Klammer.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!