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..
Beiträge von lauras
-
-
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:JavaScript
Alles anzeigenfunction whatever(){ var ret; $.ajax({ url: 'wherever', async: false }) .done(function(data){ ret = data; }); return ret; }
(was ganz nebenbei auch das erste google-Ergebnis ist.. *räusper*)
-
Wie meinst du? Dass man auf einen Link o.Ä. klickt und dann ein Bild heruntergeladen wird?
-
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
PHP
Alles anzeigen<?php class DB { /** * stores established database connection * @var mysqli connection */ public static $db = null; } ?>
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
PHP
Alles anzeigen/** * init db connection * @param string $dbHost db host * @param string $dbUser db user * @param string $dbPassword db password * @param string $dbName db name */ public static function init($dbHost, $dbUser, $dbPassword, $dbName) { self::$db = new mysqli($dbHost, $dbUser, $dbPassword, $dbName); if (self::$db->connect_errno) { $_SESSION['errors'][] = "MySQL connection failed: ". self::$db->connect_error; } self::$db->query("SET NAMES utf8;"); }
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:Schritt 3.1: select
PHP
Alles anzeigen/** * select data from specified table * @param string $table database table to select from * @param array $columns colums to select, default all * @param array $where where condition * @param string $limit limit * @return array fetched data */ public static function select($table, $columns = '*', $where = null, $limit = null, $debug = false) { $sql = "SELECT " . self::generateColumnList($columns) . " FROM $table"; if ($where != null) { $sql .= " WHERE ".$where; } if ($limit != null) { $sql .= " LIMIT ".$limit; } if ($debug == true) { $_SESSION['debug'][] = __FUNCTION__ . ': $sql is <strong>' . $sql . '</strong>'; } $result = self::$db->query($sql); if (self::$db->errno) { $_SESSION['errors'][] = '<p>select failed: ' . self::$db->error . '<br> statement was: <strong>' . $sql . '</strong></p>'; return array(); } else { $ret = array(); while ($row = $result->fetch_assoc()) { $ret[] = $row; } if (count($ret) == 1) { return $ret[0]; } else { return $ret; } } }
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:
gibt einfach alle Einträge der user-Tabelle zurück
gibt alle Einträge der user-Tabelle zurück, bei denen die Spalte active auf 1 gesetzt ist.
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
PHP
Alles anzeigen/** * insert an entry to the specified table * @param string $table database table to insert into * @param array $data data to insert */ public static function insert($table, $data, $debug = false) { $keys = ""; $values = ""; foreach ($data as $key => $value) { $key = self::escape($key); $value = self::escape($value); $keys .= $key . ", "; if ($value == null) { $values .= "null, "; } else { $values .= "'" . $value . "', "; } } $keys = rtrim($keys, ', '); $values = rtrim($values, ', '); $sql = "INSERT INTO $table (" . $keys . ") VALUES (" . $values . ")"; if ($debug == true) { $_SESSION['debug'][] = __FUNCTION__ . ': $sql is <strong>' . $sql . '</strong>'; } self::$db->query($sql); if (self::$db->errno) { $_SESSION['errors'][] = '<p>' . __FUNCTION__ . ' failed: ' . self::$db->error . '<br> statement was: <strong> ' . $sql . '</strong></p>'; } }
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:
Schritt 3.3: update
PHP
Alles anzeigen/** * update an entry in specified table * @param string $table database table to update * @param string $id id of dataset to update * @param array $data updated data */ public static function update($table, $id, $data, $debug = false) { $sql = "UPDATE $table SET "; foreach ($data as $key => $value) { $key = self::escape($key); $value = self::escape($value); if ($value == null) { $sql .= "$key = null, "; } else { $sql .= "$key = '$value', "; } } $sql = rtrim($sql, ", "); $sql .= " WHERE " . self::getPrimaryKeyColumn($table) . " = $id"; if ($debug == true) { $_SESSION['debug'][] = __FUNCTION__ . ': $sql is <strong>' . $sql . '</strong>'; } self::$db->query($sql); if (self::$db->errno) { $_SESSION['errors'][] = '<p>' . __FUNCTION__ . ' failed: ' . self::$db->error . '<br> statement was: <strong> ' . $sql . '</strong></p>'; } }
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:
Schritt 3.4: delete
PHP
Alles anzeigen/** * delete data from specified table * @param string $table database table to delete from * @param string $id id of dataset to delete */ public static function delete($table, $id, $debug = false) { $sql = "DELETE FROM $table WHERE " . self::getPrimaryKeyColumn($table) . " = $id"; if ($debug == true) { $_SESSION['debug'][] = __FUNCTION__ . ': $sql is <strong>' . $sql . '</strong>'; } self::$db->query($sql); if (self::$db->errno) { $_SESSION['errors'][] = '<p>' . __FUNCTION__ . ' failed: ' . self::$db->error . '<br> statement was: <strong>' . $sql . '</strong></p>'; } }
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:
Schritt 3.5: query
PHP
Alles anzeigen/** * querys sql on database * @param string $sql sql to query * @return mixed result set */ public static function query($sql, $debug = false) { $result = self::$db->query($sql); if ($debug == true) { $_SESSION['debug'][] = __FUNCTION__ . ': $sql is <strong>' . $sql . '</strong>'; } if (self::$db->errno) { $_SESSION['errors'][] = '<p>' __FUNCTION__ . ' failed: ' . self::$db->error . '<br> statement was: <strong>' . $sql . '</strong></p>'; } return $result; }
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: generateColumnListPHP
Alles anzeigen/** * generates list of columns from array * @param array $columns array of columns * @return string imploded array */ private static function generateColumnList($columns) { if (is_array($columns)) { return implode(', ', $columns); } else { return $columns; } }
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
PHP
Alles anzeigen/** * get primary key column from given table * @param string $table table to get primary key from * @return string primary key column name */ public static function getPrimaryKeyColumn($table, $debug = false) { $sql = "SHOW KEYS FROM $table WHERE key_name = 'PRIMARY'"; if ($debug == true) { $_SESSION['debug'][] = __FUNCTION__ . ': $sql is <strong>' . $sql . '</strong>'; } $result = self::$db->query($sql); while ($row = $result->fetch_assoc()) { return $row['Column_name']; } if (self::$db->errno) { $_SESSION['errors'][] = '<p>' . __FUNCTION__ . ' failed: ' . self::$db->error . '<br> statement was: <strong>' . $sql . '</strong></p>'; } return false; }
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:Zusätzlich fügen wir am Ende der insert-Funktion noch folgende Zeile ein:
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:PHP
Alles anzeigen<?php class DB { /** * stores established database connection * @var mysqli connection */ public static $db = null; /** * id of last inserted row * @var string */ public static $insertID; /** * initialise db connection * @param string $dbHost db host * @param string $dbUser db user * @param string $dbPassword db password * @param string $dbName db name */ public static function init($dbHost, $dbUser, $dbPassword, $dbName) { self::$db = new mysqli($dbHost, $dbUser, $dbPassword, $dbName); if (self::$db->connect_errno) { $_SESSION['errors'][] = "MySQL connection failed: ". self::$db->connect_error; } self::$db->query("SET NAMES utf8;"); } /** * querys sql on database * @param string $sql sql to query * @return mixed result set */ public static function query($sql, $debug = false) { $result = self::$db->query($sql); if ($debug == true) { $_SESSION['debug'][] = __FUNCTION__ . ': $sql is <strong>'.$sql.'</strong>'; } if (self::$db->errno) { $_SESSION['errors'][] = "<p>insert failed: " . self::$db->error . "<br> statement was: <strong> $sql </strong></p>"; } return $result; } /** * insert an entry to the specified table * @param string $table database table to insert into * @param array $data data to insert */ public static function insert($table, $data, $debug = false) { $keys = ""; $values = ""; foreach ($data as $key => $value) { $key = self::escape($key); $value = self::escape($value); $keys .= $key . ", "; if ($value == null) { $values .= "null, "; } else { $values .= "'" . $value . "', "; } } $keys = rtrim($keys, ', '); $values = rtrim($values, ', '); $sql = "INSERT INTO $table (" . $keys . ") VALUES (" . $values . ")"; if ($debug == true) { $_SESSION['debug'][] = __FUNCTION__ . ': $sql is <strong>' . $sql . '</strong>'; } self::$db->query($sql); if (self::$db->errno) { $_SESSION['errors'][] = '<p>' . __FUNCTION__ . ' failed: ' . self::$db->error . '<br> statement was: <strong> ' . $sql . '</strong></p>'; } self::$insertID = self::$db->insert_id; } /** * update an entry in specified table * @param string $table database table to update * @param string $id id of dataset to update * @param array $data updated data */ public static function update($table, $id, $data, $debug = false) { $sql = "UPDATE $table SET "; foreach ($data as $key => $value) { $key = self::escape($key); $value = self::escape($value); if ($value == null) { $sql .= "$key = null, "; } else { $sql .= "$key = '$value', "; } } $sql = rtrim($sql, ", "); $sql .= " WHERE " . self::getPrimaryKeyColumn($table) . " = $id"; if ($debug == true) { $_SESSION['debug'][] = __FUNCTION__ . ': $sql is <strong>' . $sql . '</strong>'; } self::$db->query($sql); if (self::$db->errno) { $_SESSION['errors'][] = '<p>' . __FUNCTION__ . ' failed: ' . self::$db->error . '<br> statement was: <strong> ' . $sql . '</strong></p>'; } } /** * select data from specified table * @param string $table database table to select from * @param array $columns colums to select, default all * @param array $where where condition * @param string $limit limit * @return array fetched data */ public static function select($table, $columns = '*', $where = null, $limit = null, $debug = false) { $sql = "SELECT " . self::generateColumnList($columns) . " FROM $table"; if ($where != null) { $sql .= " WHERE ".$where; } if ($limit != null) { $sql .= " LIMIT ".$limit; } if ($debug == true) { $_SESSION['debug'][] = __FUNCTION__ . ': $sql is <strong>' . $sql . '</strong>'; } $result = self::$db->query($sql); if (self::$db->errno) { $_SESSION['errors'][] = '<p>select failed: ' . self::$db->error . '<br> statement was: <strong>' . $sql . '</strong></p>'; return array(); } else { $ret = array(); while ($row = $result->fetch_assoc()) { $ret[] = $row; } if (count($ret) == 1) { return $ret[0]; } else { return $ret; } } } /** * delete data from specified table * @param string $table database table to delete from * @param string $id id of dataset to delete */ public static function delete($table, $id, $debug = false) { $sql = "DELETE FROM $table WHERE " . self::getPrimaryKeyColumn($table) . " = $id"; if ($debug == true) { $_SESSION['debug'][] = __FUNCTION__ . ': $sql is <strong>' . $sql . '</strong>'; } self::$db->query($sql); if (self::$db->errno) { $_SESSION['errors'][] = '<p>' . __FUNCTION__ . ' failed: ' . self::$db->error . '<br> statement was: <strong>' . $sql . '</strong></p>'; } } /** * 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); } /** * get primary key column from given table * @param string $table table to get primary key from * @return string primary key column name */ public static function getPrimaryKeyColumn($table, $debug = false) { $sql = "SHOW KEYS FROM $table WHERE key_name = 'PRIMARY'"; if ($debug == true) { $_SESSION['debug'][] = __FUNCTION__ . ': $sql is <strong>' . $sql . '</strong>'; } $result = self::$db->query($sql); while ($row = $result->fetch_assoc()) { return $row['Column_name']; } if (self::$db->errno) { $_SESSION['errors'][] = '<p>' . __FUNCTION__ . ' failed: ' . self::$db->error . '<br> statement was: <strong>' . $sql . '</strong></p>'; } return false; } /** * generates list of columns from array * @param array $columns array of columns * @return string imploded array */ private static function generateColumnList($columns) { if (is_array($columns)) { return implode(', ', $columns); } else { return $columns; } } } ?>
Und fertig ist unsere sehr einfache Datenbankklasse - mehr Tutorials folgen
-
I.d.R. ist sowas doch aber in den meisten Projektverwaltungs-Systemen integriert? Wo siehst du die Vorteile, das seperat zu haben?
-
Bei mir funktioniert das weder bei Windows 7 noch bei Windows 8 in zwei verschiedenen Versionen..
-
Außer man gibt ihnen Kommando
Und was spricht dagegen ihnen eben dieses Kommando zu geben? Floats lassen sich in den wenigsten Fällen komplett vermeiden, außer man positioniert absolut.
-
Das ist ja alles schön und gut, wird aber nicht funktionieren sobald der User in seinem Browser die Desktop-Seite anfordert..
-
-
Es gibt da ein geschicktes Addon, SideBarEnhancements, damit kann man auf jeden Fall Dateien verschieben, löschen, umbenennen etc, was dann auf jeden Fall auch im Dateisystem geschieht und nicht nur 'virtuell'
-
wolf: Da der IE 1.5 aber 0,0% Marktanteil hat ist er völlig irrelevant (falls du wirklich den originalen hast und keinen Emulator, welche zum Browser-Testen nie benutzt werden sollten). Relevant sind die noch unterstützten und noch in den Statistiken auftauchenden (der niedrigste dort ist momentan glaube 6).
-
Diebstahlschutz habe ich auch drauf, alles andere ist irgendwie überflüssig wenn man ein bisschen aufpasst
-
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. -
Ein Dualboot-System hilft
-
Es macht durchaus schon noch Sinn, die Elemente für die alten IE versionen anzumelden, damit dieser nicht alles zerhaut, allerdings gibt es dafür schon zusammenfassende Skripte, die man einfach einbinden kann (siehe hier).
-
Immerhin benutzt du Ubuntu, da machst du schon mal einiges richtig
-
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?)