Beiträge von lauras

    Ich würde Mehrsprachigkeit gar nicht unbedingt per Datenbank umsetzen - so hast du das Problem, dass du nur mit PHP drankommst. Was machst du wenn du mal z.B. mit Javascript ran musst, jedes Mal nen AJAX-Aufruf? Nebenbei müsstest du die Datenbankspalten alle als TEXT deklarieren, weil dir VARCHAR mit seinen 255 Zeichen tendenziell nicht für alle Fälle ausreicht.
    XML-Dateien eignen sich da wesentlich besser und sind flexibler..

    Dann logischerweise wie Basiii gesagt hat auf keinen Fall synchron. Verabschiede dich einfach von deinem return (warum eigentlich?? Sinn??) und mach es wie jeder normale Mensch in der .done() (oder ruf von mir aus in der .done() eine andere Funktion auf mit nem Parameter der deinem return-Wert entspricht wenn du grundsätzlich dagegen bist schon vorhandene Funktionen anhand ihrer vorgesehenen Funktionalität zu benutzen).

    Weil du wie nun schon mehrmals erwähnt in der .done()-Funktion arbeiten musst, da ein AJAX-Aufruf asynchron ist.. Das Zuweisen an obj ist ja schön und gut, passiert aber auch erst nachdem der Aufruf durch ist, während der darauf folgende Code sofort ausgeführt wird.
    Und was genau spricht gegen:

    JavaScript
    .done(function( output ) {
            if (whatever) {
               alert('Du kannst den Benutzernamen nicht benutzen!');
            }
    });


    Nebenbei: Wenn der restliche Fortlauf deines Skriptes komplett davon abhängt, was vom php-Skript zurückkommt, wäre es evtl. sinnvoll, die Asynchronität des AJAX-Aufrufs auszuschalten. Dann wartet das Skript halt und du kannst dein return machen:

    (was ganz nebenbei auch das erste google-Ergebnis ist.. *räusper*)

    cottton: kein Wink, reiner Zufall. Ich hatte diesen Post gar nicht als Tutorial wahrgenommen, sonst hätte ich das Präfix direkt wieder rausgenommen. Nebenbei hoffe ich dass du den Unterschied zwischen einem Schritt für Schritt Tutorial und unordentlich dahingeklatschtem Code erkennen kannst.

    Zu dem was Basiii gesagt hat: meiner Meinung nach gerechtfertigte Kritik (wenn du etwas hier postest solltest du in der Lage sein Kritik anzunehmen und im Idealfall produktiv umzusetzen - 'über den Rest kann man sich streiten und dazu hab ich keinen bock' ist da irgendwie eher unangebracht? - wenn du nicht kritikfähig bist solltest du dir das mit dem posten hier evtl nochmal überlegen)
    Nochmal für dich aufgeschlüsselt:
    - was soll dieser Post bringen? Ein Tutorial ist es nicht, eine Frage hast du denke ich auch nicht. Die Information fehlt in deinem ursprünglichen Post komplett, in deiner Antwort dann so ein halber Nebensatz
    - die Aussage 'wer PDO noch nicht nutzt ist selber Schuld' ist in einem Forum mit diesem Kontext tatsächlich eher fehl am Platz - eher angebracht wäre eher etwas ala 'für Anfänger reicht normales MySQLi vollkommen aus, aber für alle die sich ein wenig weiter damit beschäftigen wollen.. Hier sind die Vorteile und so benutzt man es'
    - die meisten der Code-Kommentare sind entweder unnötig (für Fortgeschrittene) oder nicht erläuternd genug (für Anfänger - da wäre dann ein Tutorial evtl angebrachter), außerdem da du dich an null Konventionen hältst sehr schlecht lesbar (was irgendwie für den kompletten Code gilt)

    @TheScout: prinzipiell ja, allerdings kann man ja auch mal über eine Datenbank stolpern die nicht UTF-8 codiert ist - man kann sich ja nie sicher sein, was man z.B. von anderen Leuten bekommt, deshalb immer vorher prüfen :)

    (Da es anscheinend immer noch Unklarheiten über den Begriff "Tutorial" gibt, hier mal ein Beispiel wie ein Tutorial aufgebaut sein sollte)

    Ziel: eine einfache Datenbankklasse erstellen, über die leicht einfache Anfragen an die Datenbank gestellt werden können
    Verwendete Techniken: PHP, MySQLi
    Schwierigkeitsgrad: für Anfänger geeignet, Grundkenntnisse über die Funktionsweisen von PHP, OOP und SQL vorausgesetzt
    Anmerkungen: keine PDO, weil in diesem Fall unnötig und für Anfänger nur bedingt geeignet. Kommentare und Fragen sind gerne gesehen, werden in den Beitrag eingebaut und danach gelöscht um den Thread übersichtlich zu halten.
    Kommentare: der Code ist mit Blockkommentaren versehen, die die entsprechenden Attribute bzw. Methoden zusammenfassen. Diese Kommentare sind nach Konvention in englischer Sprache verfasst, für das Verständnis des Codes allerdings nicht notwendig, dafür gibt es das Tutorial. Da man Codes allerdings immer kommentieren sollte (vor allem wenn andere Leute ihn verwenden, aber auch für einen selbst) habe ich diese drin gelassen.
    Fehlerbehandlung: die Klasse schreibt Fehler in ein error-Array der aktuellen Session, die dann an beliebiger Stelle ausgegeben werden können. Alternativ kann man die Fehler natürlich auch direkt ausgeben, dies kann aber je nach Seitenaufbau problembehaftet sein. Natürlich kann man dies auch anders lösen, z.B. mit einer weiteren Funktion error o.Ä.
    Debugging: die meisten Methoden bekommen als letzten Parameter einen boolean-Wert $debug übergeben, der falls gesetzt dafür sorgt, dass Informationen zur momentanen Situation in ein debug-Array der aktuellen Session geschrieben werden, welches dann ähnlich wie das error-Array an beliebiger Stelle ausgegeben werden kann. Natürlich kann man dies auch anders lösen, z.B. mit einer weiteren Funktion debug o.Ä.

    Schritt 1: Was soll die Klasse können?
    Am Anfang steht immer die Frage "was will ich eigentlich erreichen?". Um das ganze einfach und kompakt zu halten (vorerst - das gute an OOP ist ja das Erweiterungen sehr einfach sind), beschränken wir uns auf die wesentlichen Funktionen: Datenbankverbindung herstellen, SELECT-, INSERT-, UPDATE- und DELETE-Anfragen.

    Schritt 2: Struktur
    Da wir die DB-Klasse ständig verfügbar haben wollen, die ohne jedes Mal eine Instanz z.B. als Funktionsargument zu übergeben benutzbar ist, sind die Attribute (Variablen) und Methoden (Funktionen) unserer Klasse statisch (Schlüsselwort static). Da wir die Klasse nicht instanziieren, brauchen wir keinen Konstruktor, stattdessen eine init-Methode, die die Datenbankverbindung aufbaut. Weiterhin möchten wir eine select-Methode, eine insert-Methode, eine update-Methode und eine delete-Methode, die jeweils entsprechende Queries ausführen, ohne dass wir sie jedes Mal selber schreiben müssen. Da diese Funktionen sehr einfach gestrickt sein sollen, möchten wir außerdem noch eine query-Methode für komplexere Anfragen (z.B. JOINs), die einfach eine übergebene Query ausführt und das Ergebnis ohne Aufbereitung zurückliefert. Als Klassenattribut brauchen wir vorerst nur eine noch leere Instanz der Datenbankverbindung, auf die alle Methoden zugreifen.

    Schritt 3: Grundgerüst


    Unsere Klasse heißt ganz einfach DB (da wir statische Methoden haben ist es gut den Namen so kurz wie möglich zu halten, sonst muss man immer so viel tippen beim Aufrufen). Die Klasse hat ein Attribut $db, in welches wir später unsere MySQL-Verbindung speichern. Das Attribut ist private, da wir es lediglich in der Klasse selbst brauchen. Wir initialisieren auf null, da die Verbindung erst später in der init-Methode hergestellt wird.

    Schritt 3: Hauptfunktionen
    Die Hauptfunktionen unserer Klasse sind: init, select, insert, update, delete, query. Während dieses Tutorials werden wir über einige Hilfsfunktionen stolpern, diese werden dann nach allen Hauptfunktionen in Schritt 4 erklärt.

    Schritt 3.1: init


    Die init-Funktion bekommt vier Parameter übergeben: $dbHost (z.B. localhost), $dbUser und $dbPassword zur Authentifikation sowie den Namen der Datenbank auf die verbunden werden soll als $dbName. Mit diesen Parametern wird dann in Zeile 9 eine neue MySQLi-Verbindung geöffnet und in die $db-Variable der Klasse gespeichert. Falls es dabei einen Fehler gibt, wird dieser ins error-Array geschrieben.
    Anschließend wird noch der Zeichensatz der aktuellen Verbindung auf utf-8 gesetzt, um Zeichensatzprobleme zu vermeiden.
    Der Aufruf der init-Methode sollte idealerweise in einer config oder init-Datei erfolgen, auf jeden Fall aber vor der ersten Datenbankverbindung (logischerweise). Der Aufruf erfolgt wie folgt:

    PHP
    DB::init(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); // die Konstanten natürlich vorher setzen


    Schritt 3.1: select


    Die select Funktion bekommt eine ganze Reihe an Parametern übergeben: $table ist der Name der Tabelle, aus der selected werden soll, $columns (optional) ist entweder ein Array mit den Spalten oder ein String, falls nur eine Spalte ausgewählt werden soll, $where und $limit (beide optional) sind die entsprechenden WHERE und LIMIT Bedingungen, wenn gewünscht, zusätzlich der optionale $debug-Parameter.
    Da wir in $columns entweder einen String oder ein Array haben, bedienen wir uns der generateColumnList-Methode (siehe 4.1), die aus dem übergebenen Wert einen für den SQL-Befehl verwendbaren String generiert. Falls die $where und $limit Parameter nicht null sind, wird an das SQL die entsprechende Bedingung angehängt, anschließend wird die Query ausgeführt. Falls ein Fehler auftritt wird dieser ins error-Array geschrieben und ein leeres Array zurückgegeben. Falls die Query fehlerfrei durchläuft, wird anschließend jede Zeile des Ergebnisses in das $ret-Array geschrieben, welches am Ende zurückgegeben werden soll.
    Hat dieses Array, nachdem alle Ergebnisse hineingepackt wurden, nur ein Element, so wird nur dieses eine Element zurückgegeben, ansonsten das komplette Array.

    Diese Funktion kann nun verschiedene Aufrufe handlen:

    PHP
    $result = DB::select('user');


    gibt einfach alle Einträge der user-Tabelle zurück

    PHP
    $result = DB::select('user', '*', 'active = 1');


    gibt alle Einträge der user-Tabelle zurück, bei denen die Spalte active auf 1 gesetzt ist.

    PHP
    $result = DB::select('user', 'username', 'active = 1', 20, true);


    gibt die ersten 20 username-Spalten der user-Tabelle zurück, bei denen die Spalte active auf 1 gesetzt ist, zusätzlich soll debugged werden.


    Schritt 3.2: insert


    Die insert-Methode bekommt zwei Parameter übergeben: $table ist der Tabellenname, $data ist ein Array mit den einzufügenden Daten. Optional kann noch der $debug Parameter übergeben werden.
    Zuerst werden zwei leere Strings initialisiert, $keys und $values. Diese sollen später unsere keys und values für die Insert-Anweisung enthalten. In einer Schleife wird anschließend das $data-Array durchlaufen und die Werte an die entsprechenden Strings angehängt. Hier bedienen wir uns einer weiteren Hilfsfunktion escape (siehe 4.2), welche die übergebenen Strings für den Eintrag in die Datenbank escaped. Da wir beim Anhängen immer ein Komma mit angehängt haben aber natürlich am Ende der Strings kein Komma mehr wollen, entfernen wir anschließend mit der PHP-eigenen Funktion rtrim alle Kommas und Leerzeichen vom rechten Rand der beiden Strings.
    Nun bauen wir die insert-Anweisung korrekt zusammen, speichern sie ggf. im debug-Array, führen sie aus und speichern eventuelle Fehler ab.

    Der Aufruf erfolgt dann wie folgt:

    PHP
    DB::insert('user', array(
        'username' => 'test',
        'name' => 'Tester',
        'active' => 1));


    Schritt 3.3: update


    Die update-Funktion arbeitet ähnlich wie die insert-Funktion (mit dem Unterschied, dass aufgrund der unterschiedlichen Syntax von insert- und update-Anweisungen der String direkt ohne Hilfsstrings zusammengebaut wird), bekommt aber als Parameter zusätzlich noch die id des zu updatenden Datensatzes übergeben. Dies erfordert die Existenz einer Primary Key Spalte (!!) in der Tabelle. Dies ist i.d.R. eine Spalte, die jeden Datensatz durch auto_increment mit einer ID versieht. Wir setzen eine weitere Hilfsfunktion getPrimaryKeyColumn (siehe 4.3) ein, welche uns den Namen dieser Spalte in der Tabelle $table zurückliefert, welche dann in der WHERE-Bedingung eingebaut wird, um den entsprechenden Datensatz zu updaten. Da die ID immer unique ist, kann man mit der update Funktion in dieser Form natürlich nur einzelnde Datensätze updaten. Für einfache Zwecke ist das auch erstmal ausreichend. Am Ende erfolgt die übrige Prozedur.

    Der Aufruf erfolgt dann wie folgt:

    PHP
    DB::update('user', 1, array('active' => 0));


    Schritt 3.4: delete


    Auch die delete-Funktion hat Ähnlichkeiten mit der update-Funktion, denn auch hier wird wieder eine Tabelle und die ID des zu löschenden Datensatzes übergeben. Daten brauchen wir nicht mehr, schließlich wollen wir ja löschen. Die Query wird wieder mit Hilfe der getPrimaryKeyColumn-Funktion aufgebaut und anschließend in gewohnter Manier ausgeführt.

    Der Aufruf erfolgt dann wie folgt:

    PHP
    DB::delete('user', 1);


    Schritt 3.5: query


    Für alle anderen SQL-Anfragen, die komplexer sind als die durch die anderen Funktionen abgedeckten Szenarien, fügen wir noch eine query-Funktion hinzu, die übergebenes SQL einfach ausführt.


    Schritt 4: Hilfsfunktionen
    Schritt 4.1: generateColumnList


    Da diese Funktion nur von innerhalb der Klasse zugänglich sein soll, ist sie private. Als Parameter kommt ein Array oder ein String an. Falls $columns ein Array ist, wird dieses per implode zu einem durch Kommas getrennten String gemacht, falls $columns ein String ist so wird dieser einfach unverändert wieder zurückgegeben. Die Funktionalität der Funktion ist so sehr einfach, allerdings könnte man z.B. sehr einfach noch eine weitere Bestandteile aufnehmen, wenn gewünscht (column as name Unterstützung o.Ä.).


    Schritt 4.2: escape

    PHP
    /**
    	 * escape given string
    	 * @param  string 	$string string to escape
    	 * @return string         	escaped string
    	 */
    	public static function escape($string) {
    		return self::$db->real_escape_string($string);
    	}


    Diese Funktion liefert einfach den escapeden String zurück. Auch hier könnte man noch weitere Dinge einbauen, z.B. Ersetzungen o.Ä. Da eine solche Funktion evtl. auch außerhalb der Klasse von Nutzen sein sollte, machen wir sie public.


    Schritt 4.3: getPrimaryKeyColumn


    Diese Funktion soll den Namen der PK-Spalte der übergebenen Tabelle zurückgeben. Dafür wird eine entsprechende Query zusammengebaut und anschließend die Spalte Column_name der ersten Zeile (mehr als eine sollte es eh nicht sein) des Ergebnisses zurückgegeben. Da auch diese Funktion evtl. noch anderweitig von Nutzen sein könnte, machen wir auch diese public.


    Schritt 5: insertID
    Ein bisher noch nicht genanntes 'Feature' unserer Klasse soll die sogenannte insertID werden. Diese ID wird von der Datenbank nach einem insert geliefert und ist die eindeutige ID des gerade eingefügten Datensatzes. Mithilfe der insertID kann man mit dem gerade eingefügten Datensatz sehr einfach weiter arbeiten.
    Diese insertID wollen wir als öffentlich zugängliches Attribut unserer Klasse speichern, deshalb fügen wir nach der Deklaration des Attributes $db folgendes ein:

    PHP
    /**
    	 * id of last inserted row
    	 * @var string
    	 */
    	public static $insertID;

    Zusätzlich fügen wir am Ende der insert-Funktion noch folgende Zeile ein:

    PHP
    self::$insertID = self::$db->insert_id;


    dadurch wird das in der Datenbank-Instanz vorhandene Attribut insert_id in unsere Variable insertID geschrieben (die unterschiedliche Schreibweise ist hier reine persönliche Vorliebe - natürlich könnte man die Klassenvariable auch $insert_id nennen).


    Schritt 6: Komplettcode
    Zum Schluss der nun komplette Code nochmal im Überblick:

    Und fertig ist unsere sehr einfache Datenbankklasse - mehr Tutorials folgen :)

    Ich würde mir da gar nicht so viele Gedanken drum machen.. Generell ist es anderen Leuten verboten, Bilder die dir gehören oder die du erstellt hast weiterzuverwenden (gleiches gilt für Texte), wenn du es nicht erlaubt hast (Stichwort UrhG). Sprich wenn jemand dein Bild runterlädt und weiterverwendet, kannst du ihn i.d.R. abmahnen (was sich allerdings nur lohnt wenn er damit auch Profit macht und wenn nicht - warum sollte es dich stören?).
    Du musst es natürlich beweisen, die einfachste Möglichkeit dafür ist die RAW-Dateien der Kamera aufzubewaren oder wenn du die nicht hast zumindest die EXIF-Daten richtig zu setzen. Jemand der nicht viel Ahnung davon hat wird sich nicht darum kümmern diese zu ändern, und jemanden der Ahnung hat kannst du i.d.R. sowieso nur sehr schwer davon abhalten dir etwas zu klauen.

    Probier doch mal, das Fenster immer gleich groß zu lassen und nur innerhalb des Fensters die Größe des Bereichs zu verändern - dann springt das nicht immer so hin und her ;) (und der slider funktioniert immer noch nicht, oder?)