Die Funktion ist nicht alles..

  • Hi Leutz,

    da ich hier immer wieder in euren Codes Sachen sehe, die mich total aggressiv machen, möchte ich euch jetzt ein paar Tipps geben, wie ihr mein Leben hier erträglicher machen könnt. Vielen Dank für eure Aufmerksamkeit!

    Also fangen wir einfach mal klein bei Numero 1 an. Hier hätten wir ein kleines Script:

    Okay. Dieses Problem ist jetzt nicht all zu tragisch, kann jeder falsch machen. Trotzdem könnte es in diesem Fall erhebliche Performance Probleme geben, falls viele Einträge vorhanden sind. Erahnt ihr das Problem?

    Hier ist die Auflösung:

    Spoiler anzeigen


    Nehmen wir mal 2 Sachen aus dem Code..

    PHP
    $_POST['flags'] = trim(mysql_real_escape_string(htmlspecialchars($_POST['flags'])));
     mysql_query('INSERT INTO ... (flags, content) VALUES (\''.$_POST['flags'].'\',\' '.$_POST['content'].'\');


    So, was können wir feststellen? $_POST['flags'] wird in der ersten Zeile für die SQL-Abfrage escapt und dann zusätzlich noch gegen XSS-Attacken und (teilweise) gegen Spam geschützt. Danach wird $_POST['flags'] in eine Tabelle eingetragen. Soll auch so sein, hier können wir keinen Fehler entdecken.
    Nehmen wir noch ein paar Zeilen raus:

    PHP
    while ($row = mysql_fetch_array($qr)) {
          echo htmlspecialchars($row[0]) . '<br />';
    }


    Wir sehen, dass es wieder vor HTML gesichert wird, nämlich 2-mal. Etwas unnötig, oder? Das ist nur ein kleines Beispiel so was könnte man bei etlichen anderen Funktionen auch machen. Aber bedenkt bitte: Falls ein Eintrag geändert/hinzugefügt werden kann, wo er nicht gegen HTML gesichert wird und man keinen Zugriff auf diese Server-Dateien hat, dann empfehle ich euch die XSS-Protection in der SQL-Query einfach wegzulassen und sie bei der Ausgabe stehen zu lassen.

    Schön und gut, weiter geht es mit der 2. Da hätten wir noch ein Script:

    PHP
    <?php
    // mysql connection und so weiter..
    $q = mysql_fetch_assoc(mysql_query('SELECT * FROM ... ORDER BY id DESC LIMIT 1'));
    echo 'Hallo.. der neuste Benutzer hat die ID '.$q['id'].' und er hat '.$q['coins'].' Taler!';
    ?>


    Wer kennt das Problem? Die Lösung:

    Spoiler anzeigen


    Wenn du die Query..

    SQL
    SELECT * FROM ... ORDER BY id DESC LIMIT 1


    .. hast, dann werden mit * alle Spalten abgefragt, da wir aber nur zwei brauchen werden hier etliche andere Spalten umsonst abgefragt.
    Also.. kurz und knapp: Wenn du z.b. nur ID und Taler eines Users abfragen möchtest und nicht mehr brauchst, dann musst du nicht mehr eingeben als

    SQL
    SELECT id, coins FROM ... ORDER BY id DESC LIMIT 1


    Simpel, nicht?
    Und falls du am Ende nur eine Spalte abfragen möchtest, empfehle ich dir die Funktion 'mysql_result'.

    PHP
    <?php
    // mysql.. balbla
    echo 'Blabla hat die User ID: ' . mysql_result(mysql_query('SELECT id FROM ...'), 0);
    ?>

    Alle guten Dinge sind drei.. kommen wir zum 3ten Punkt:

    PHP
    <?php
    $count = '1';
    echo $count;
    ?>


    Okay.. das Problem müsste jeder erkennen.

    Spoiler anzeigen


    In PHP muss man keine Datentypen angeben, weswegen die Sprache sehr oft von Anfängern gelernt wird, da sie unkompliziert ist und alle denken, sie müssen sich keine Gedanken über den Speicher machen. Es gibt in PHP (versteckt) unter anderem Datentypen wie Integer (Zahl) und String (Kette von Zeichen) oder Boolean (wahr oder falsch). Jeder Datentyp verbraucht eine andere Anzahl an Bits und hat speziell dafür gemachte Methoden. Mit den zwei Zeichen " und ' initialisiert du normalerweise einen String, für einen Integer reicht einfach nur eine Zahl. Wir sehen also oben im Code $count wird als String initialisiert und hat als Inhalt eine Zahl. Wieso nicht gleich als Integer initialisieren? So würde $count unter anderem weniger Speicher verbrauchen und bei Rechenoperationen müsste der String nicht immer in einen Integer umgewandelt werden.

    Wir machen also stattdessen:

    PHP
    <?php
    $count = 1;
    echo $count;
    ?>

    So, das waren erstmal 3. Mir fallen noch 1000 weitere ein, aber ich hatte jetzt einfach keine Lust mehr weiterzuschreiben. Gegebenenfalls folgen weitere Tipps, falls ich mal wieder nichts zu tun habe.

    Cheers
    Steve Winfield

  • Am besten trägt man Sachen in die Datenbank ein ohne diese gegen XSS zuschützen.
    Erst bei der Ausgabe filtert man den eingetragenen Text, da es keinen Sinn macht etwas in der Datenbank gegen XSS zuschützen.

    Also:
    mysql_real_escape_string() beim Eintragen
    und
    htmlentities() / htmlspecialchars()
    beim Ausgeben

    Außerdem empfehle ich, dass man die Ausgabe, das was der Benutzer später sehen wird, von der Programmlogik auseinander hält.
    Um dies zu erreichen wäre es angebracht ein Template System zu verwenden.

    2 Mal editiert, zuletzt von Johnix (19. Januar 2014 um 19:35)

  • Am besten trägt man Sachen in die Datenbank ein ohne diese gegen XSS zuschützen.
    Erst bei der Ausgabe filtert man den eingetragenen Text, da es keinen Sinn macht etwas in der Datenbank gegen XSS zuschützen.

    Also:
    mysql_real_escape_string() beim Eintragen
    und
    htmlentities() / htmlspecialchars()
    beim Ausgeben

    Außerdem empfehle ich, dass man die Ausgabe, das was der Benutzer später sehen wird, von der Programmlogik auseinander hält.
    Um dies zu erreichen wäre es angebracht ein Template System zu verwenden.


    Wenn du etwas in der Datenbank gefiltert speicherst, musst du es danach nicht mehr beim Ausgeben filtern und sparst dir somit Scriptlaufzeit (Das ist genau das, was ich euch im Thread mitteilen wollte). Das mit dem Template-System ist auch nichts, was die Performance oder den Speicher beeinflusst, sondern eher eine Sache für jedermann (Empfehle ich auch nur für komplexere Projekte). Ein Template-System wie Smarty verlängert die Scriptlaufzeit sogar um ein vielfaches, also würde ich Smarty nur verwenden, wenn es wirklich benötigt wird.

    Cheers
    Steve Winfield

Jetzt mitmachen!

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