Beiträge von cottton

    Für "best practice" kann ich nicht sprechen -- da weiß ich nicht genug @JS.
    Ich habe es aber für mich in einer PHP-ähnlichen Art festgemacht.
    Bsp:


    siehe auch http://www.peterkropff.de/site/javascript/oop.htm

    prototype ist mir zu "unübersichtlich". Wäre aber wohl die richtige Wahl. Muss man abwiegen, wie "kompliziert" man seine JS Scripte schreiben will.

    PHP
    define('CONTENTS', 'contents/');
    // ...
    include CONTENTS . $ls_filename;


    wo liegt denn die Datei Register.php ?
    Du musst sicherlich noch den Pfad anpassen: contents/ zu Deinem Pfad

    Ich schätze, weil ein Großteil schon ge-updated wurde.
    Auch, wenn das Script vorher immer abgebrochen wurde, hat der SQL-Server "ein paar" UPDATE -Statements bekommen.

    PHP
    foreach($update_preise as $array) // $update_preise ist sicherlich von mal zu mal weniger geworden

    Aber wie gesagt: sowas solltest Du (wenn möglich) den SQL-Server machen lassen.

    einfach mal Testausgaben mit einbauen:

    Willst Du nur bestimmte Artikel updaten, oder überall den Preis auf ein neues Format setzen?
    Wenn alle, dann mach das mit einer Query -- lass es den SQL-Server erledigen:


    http://dev.mysql.com/doc/refman/5.7…function_format

    Es sollte keine Probleme geben, solange du festlegst, dass diese Werte (die ja manipuliert werden können per url)
    NUR in dem include-Verzeichnis genutzt werden, in denen NUR die Seiten-Klassen liegen.
    Andere Klassen-Dateien hätten dann dort drin nichts zu suchen.

    Hätte da nen Vorchlag:
    Du hast schon eine gut Idee gehabt. Du kannst es noch erweitern in dem Du:
    - angenommen order inc/controller/ enthält nur Seiten-Klassen (siehe google Controller)
    - in diesem Verzeichnis (inc/controller/) wird pro neue Seite ein Unterordner "SeitenName" angelegt (also zB Home)
    - jeder Unterordner "SeitenName" muss eine bestimmte Struktur besitzen: in inc/controller/SeitenName/ muss die Datei SeitenNameController.php mit der Klasse SeitenNameController existieren
    - die Klasse SeitenNameController muss Methoden (Funktionen) besitzen, die auf den Content leiten/zeigen/kontrollieren ...
    - die erwähnten Methoden müssen mit dem Zusatz "Action" ergänzt werden
    Jeder Controller besitzt also eine indexAction(), und andere wie zB loginAction()
    Im Bsp:

    Im Bsp für einen Login:

    Das Prinzip kenne ich von Magento. Find ich ziemlich geil. Wird aber sicherlich noch anderswo so umgesetzt.

    EDIT:
    ungetestet:

    wolf at line 28 "503 Service Unavailable"
    würde ich ändern in 404, denn 503 sagt aus, dass der Server einen Fehler (begangen) hat.
    Es ist ja aber einfach nur die request nicht valid.

    1. stimmt soweit: http://php.net/manual/de/mysq…-statements.php
    (siehe "Basic workflow")
    Hatte selbst gedacht, dass die Platzhalter ersetzt werden, bevor die Query an den Sql-Server geht.
    Muss ich selbst mal nachsehen, wie genau der Ablauf ist.
    Fakt ist aber, dass bei richtiger Anwendung keine SQL-Injectons mehr möglich sind.
    Bsp falsch und richtig:


    (siehe types: http://php.net/manual/de/mysqli-stmt.bind-param.php)
    (btw: bei PDO siehe: http://php.net/manual/de/pdo.constants.php)

    Achtung: Platzhalter können (und sollen) nicht für Tabellennamen verwendet werden.


    2. Weiß nicht genau, was Dein Script macht (include $_GET ... ?),
    aber im Grunde würde ich hier auch auf Whitelists setzen.

    PHP
    if(isset($sites[$siteName])){} ...
    // sicherlich das ganze in aussagekräftige funktionen setzten wie zB
    if(isValidSiteName($siteName)){
    	$siteName = getValidSiteName($siteName);
    	...
    } ...


    EDIT: siehe auch wolf: Include


    3. hast Du schon richtig gamacht. Wenn Du Dich daran hältst, dass in Klassen-Dateien nur die Klassen enthalten sind, dann kann nix passieren.
    Es sei denn Du kommst einmal an den Punkt, an dem Du eine ("static")Klasse initialisierst:

    PHP
    <?php
    // file MyClass.php
    class MyClass{
    	public function init(){
    		// ...
    	}
    }
    // wenn dieses file geladen wird, auto-init sich diese klasse
    MyClass::init();
    // ... kann man machen, sieht man auch öfter


    Im Grunde sollten include Ordner nicht von Aussen erreichbar sein (Server config).
    Wenn Du auf nummer sicher gehen willst, dann kannst Du eine Konstante definieren:
    - index.php ganz am Anfang: define('MAIN', 1);
    - other_scripts.php ganz am Anfang: !defined('MAIN') AND exit('meldung ...');
    (könntest auch nen Redirect auf index.php machen, wenn MAIN nicht definiert ist.)
    Ohne die definierte Konstante geht also nix.


    4. Ich hatte mal https://addons.mozilla.org/en-us/firefox/addon/xss-me/ genutzt. Ist aber lange her. Falls es jemand nutzt, dann bitte vorher prüfen/lesen, ob die Extension eine "gute" ist.
    Ansonsten denke ich, dass andere Deine Fehler besser finden, als Du selbst. (BETA)
    Also einfach mal paar vertauenswürdige auf Deine Seite los lassen. So nach dem Motto: "versucht es mal kaputt zu machen" :D
    Zum String: wenn Du Daten ausgibst, dann immer masiert.
    PHP: $secure = htmlspecialchars($inSecureData);
    JS: var secure = document.createTextNode(inSecureData);

    5. (hab mir den Namen mal wieder nicht gemerkt, aber ich glaube es hieß) Reverse-Injections:
    Stell Dir vor Du:
    - bekommst eine GET var und
    - schreibst sie per :platzhalter in die db
    - beim Anzeigen der/einer Seite lädst Du diesen Wert wieder, um ihn anzuzeigen
    Dann kann folgendes passieren:
    - bei der Ausgabe vergisst Du den Wert zu maskieren:

    PHP
    <?php
    // FALSCH:
    Das hier ist der Wert, den Sie zuvor eingegeben hatten: <?php echo $dbResult['eingabe'] ?>
    // das sollte niemals passieren! 
    // Alle geladenen Daten (aus files, db, GET, POST, SESSION, w/e) gehören maskiert ausgegeben
    // wie zB
    // RICHTIG
    Das hier ist der Wert, den Sie zuvor eingegeben hatten: <?php echo htmlspecialchars($dbResult['eingabe']) ?>

    - oder Du nutzt beim Laden von Daten den Wert aus einer Tabelle in der Query:

    Dann wird es nicht funktionieren, weil Du beim registrieren das passwort mit htmlspecialchars bearbeitest.


    Wo siehst Du denn das?
    Ich seh da nix im code.

    Aber sonst stimme ich zu.
    Am besten beim Verbinden mit der db strict tables verwenden:

    SQL
    -- connect to db
    ...
    -- set strict mode
    sql_mode = 'STRICT_ALL_TABLES'; -- einfach erklärt: wenn feld 10 zeichen lang ist, du aber 11 sendest, dann bekommst du einen fehler (so wie es sein sollte)
    -- und am besten noch:
    SET CHARSET 'utf8'; 
    NAMES 'utf8';


    guck mal im Forum -- hatten das Thema schon öfter.

    Thema Passwort: niemals das pw bearbeiten oder was auch immer.
    Das Passwort kommt vom User über das Input-Feld bis hin zu $_POST['pw...'].
    Und so wie es ankommt, sollte es auch verwendet (gespeichert) werden.
    Selbst wenn ein Leerzeichen am Anfang/Ende ist -- es ist das, was der User wollte/eingegeben hat.
    (Ich sag nur epic kack-noobs sparkasse -- die schneiden ohne Meldung alles nach 6 Zeichen ab)

    autoload ist kein kleines Thema, aber ich versuchs mal kurz:

    Es gibt verschiedene Wege -- google mal nach "php autoload psr-0" oder guck hier http://www.php-fig.org/psr/psr-0/
    Hier erstmal die spl_autoload_register():

    PHP
    spl_autoload_register(
        function($classname){}, // die eigtliche funktion zum auto-laden
        true, // throw exception wenn nicht möglich klasse zu laden
        false // prepend (vorn anhängen) diese autoload funktion (es kann mehrere geben)
    );


    Ich persönlich hatte immer eigene autoloads geschrieben - also nicht psr-0 o.ä. genutzt.
    Das sah dann zB so aus:


    Das kann aber bissl kaotisch werden, um so mehr Pfade hinzukommen. (nicht empfohlen)

    Seit dem ich mit Magento arbeite find ich deren autoload ziemlich geil:


    Was passiert da:
    Jede Klasse hat im Name den Pfad (keine Namespaces -- die sind undynamisch und braucht kein Sack).
    Unterstriche werden in Slashes umgewandelt, woraus sich der Pfad ergibt.

    PHP
    class Das_Hier_Ist_Also_Meine_Class {}
    // ergibt also den Pfad: 
    // Das/Hier/Ist/Also/Meine/Class.php


    Wenn Du nun also einen Ordner für alle includes hast, dann kannst Du:


    Das gibt lange Klassennamen, was aber auch gleich wieder von Vorteil ist:

    PHP
    // macht keinen Sinn, dient nur der "show"
    $obj = new Mage_Adminhtml_CustomerController();
    // es wird sicherlich 
    // eine Datei CustomerController.php in 
    // {inc path} Mage/Adminhtml/
    // liegen.


    Ich wette Du kannst Dir jetzt zusammenreimen, wo die Klasse Mage_Admin_Model_Resource_User_Collection liegt =)

    Stichwort "Singleton"


    Auf diese Weise ist
    - Singleton vom überall erreichbar (global)
    - zB smarty nur ein mal instanziert


    hier mal ein ausführliches Bsp / Tests:
    (hatte das Thema vor paar Wochen =)

    wolf das geht auch ohne =)
    Hat den Vorteil, dass man bei dynamischen Scripten den $key nicht immer mit einem : verbinden muss (':' . $key).

    @string97 dann sieh am besten mal nach, was für Queries am Server ankommen.
    Query log in table:

    http://stackoverflow.com/a/14404000/3411766

    Vorweg: sorry, hab nen Fehler drin gehabt: das % muss am Ende angehangen werden -- so wie Du es richtig gemacht hast =)

    Du prüfst, ob der Wert in $arr größer ist, als 0. 8|
    Willst aber sicherlich prüfen, ob:

    PHP
    if(count($arr) < 1) { echo "Kein Datensatz gefunden"; } // weniger als 1


    Oder aber noch einfacher:

    PHP
    if(empty$arr)) { echo "Kein Datensatz gefunden"; } // empty wäre zB NULL, 0, '', array(), ...

    möchte es aber mit BindParam machen wegen der Sicherheit


    :thumbup: top!

    So sollte es laufen:


    Du kanns allerdings auch ohne bindParam:

    PHP
    $sql = "SELECT id, email FROM daten WHERE email LIKE :idtag"; // '?'% entfernt, placeholder hinzugefügt
    		// parameter array für ->execute() vorbereiten:
    		$para = array(
    			'idtag' => trim((string)$_POST['id-tag']) . '%'; 
    		);
    		$stmt = $verbindung->prepare($sql);  
    		$stmt->execute($para); // para mit an execute übergeben

    Was passiert hier:
    Du übergibst (ob per bindParam oder execute($para)) einen String myemail@or.whatever%.
    PDO setzt diesen String "intern" so ein:

    SQL
    SELECT id, email FROM daten WHERE email LIKE '%myemail@or.whatever'


    Warum?
    Weil alles, was Du per execute($para) oder bindParam($key, $val, PDO::PARAM_STR) übergibst, zwischen Anführungszeichen gesetzt wird -- also al String eingesetzt wird.
    Will man etwas anderes als einen String in die Query schreiben lassen (zB für LIMIT :x :y), dann muss man
    - bindParam() nutzen
    - und bindParam() sagen, was genau man vorhat: zB bindParam($key, $val, PDO::PARAM_INT) -- einen int

    Hoffe das hilft.

    Ja, da sind schöne Sachen drin wie zB die Markierungen wenn etwas nicht genutzt wird oder nicht existiert.
    Aber die vielen vielen msgs und bunten "Dinge" sind ... naja, nicht gerade Augen/-Brain-freundlich.
    Ich meine im Gegensatz zu Sublime -- der ist total "passiv", wenn man ein angenehmes Theme nutzt. Der ist einfach nur da und macht was er soll =)