| |
 |
|
|
|
 |
|
 |
| |
10.09.2008, 18:30
|
#1 (permalink)
|
|
Erfahrener Benutzer
Registriert seit: 04.08.2008
Beiträge: 129
|
[PHP} Datenbank Klasse
PHP-Code:
<?php /** * @file * @brief Datenbanklayer * @author Hinrich Donner * * Dieser Quellcode ist urheberrechtlich geschützt. Er kann unter den Lizenzbedingungen der * GPL oder LGPL verwendet werden. * @package Datenbank */ /** * @brief Basis-Exception für Datenbank-Anfragen */ class EDatabase extends Exception { } /** * @brief Basis-Exception für MySQL-Abfragen */ class EMySql extends EDatabase { /** * @brief Konstruktor */ function __construct() { $message = sprintf('%04d: %s', mysql_errno(), mysql_error()); parent::__construct($message, mysql_errno()); } } /** * @brief Ergebnismenge einer Datenbank-Abfrage */ abstract class TDatabaseResultSet implements Iterator { /** * @brief Anzahl der Zeilen in der Ergebnismenge * @var int */ protected $_num_rows = 0; /** * @brief Die Ergebnismenge * @var array */ protected $_rows = array(); /** * @brief Konstruktor * @param resource $resource Datenbank-Resource */ /** * @brief Das aktuelle Element (Iterator) * @return array */ public function current() { return current($this->_rows); } /** * @brief Das nächste Element (Iterator) * @return array */ public function next() { return next($this->_rows); } /** * @brief Der Index des aktuellen Elements (Iterator) * @return array */ public function key() { return key($this->_rows); } /** * @brief Das erste Element (Rücksetzen des Zeigers, Iterator) * @return array */ public function rewind() { return reset($this->_rows); } /** * @brief Prüfen des aktuellen Elements (Iterator) * @return bool */ public function valid() { return (bool) is_array($this->current()); } public function get_num_rows() { return $this->_num_rows; } } /** * @brief Ergebnismenge einer MySQL-Abfrage */ class TMySqlResult extends TDatabaseResultSet { /** * @brief Konstruktor * @param resource $resource MySQL-Ergebnis-Resource */ function __construct($resource) { $this->_num_rows = 0; while ($row = @mysql_fetch_assoc($resource)) { $this->_rows[] = $row; ++ $this->_num_rows; } } } /** * @brief Abstrakte Interface-Definition */ interface IDatabase { /** * @brief Datenbankverbindung aufbauen * @param string $host IP oder Domain des Servers * @param string $user Berechtigter Benutzer * @param string $passwd Kennwort des Benutzers */ public function connect($host, $user, $passwd); /** * @brief Datenbankverbindung lösen */ public function close(); /** * @brief Datenbank auswählen * @param string $name Name der Datenbank */ public function select($name); /** * @brief Datenbankanweisung ausführen * @param string $sql Die Anweisung an die Datenbank * @return mixed */ public function execute($sql); /** * @brief Datenbankabfrage * @param string $sql Die Anweisung * @param int $offset Relativer Beginn der Ergebnismenge * @param int $limit Maximale Anzahl der Zeilen in der Ergebnismenge * @return TDatabaseResultSet */ public function query($sql, $offset = 0, $limit = -1); } /** * @brief Abstrakte Basis des Datenbank-Layers */ abstract class TDatabase implements IDatabase { /** * @brief Name der aktuellen Datenbank * @var string */ protected $database = ''; /** * @brief Datenbankhandle * @var resource */ protected $resource = false; /** * @brief Container mit den ausgeführten Anweisungen * @var array */ protected $statements = array(); /** * @brief Anzahl der ausgeführten Querys * @var int */ protected $count_querys = 0; /** * Speichert die Startzeit in Millisekunden * @var float */ protected $start = 0; /** * Speichert die Endzeit in Millisekunden * @var float */ protected $end = 0; /** * @brief Erste Zeile einer Abfrage ermitteln * @param string $sql Anweisung * @param int $offset Relativer Offset * @return TDatabaseResultSet */ public function queryRow($sql, $offset = 0) { $dbr = $this->query($sql, $offset, 1); $result = $dbr->current(); return $result; } /** * @brief Erste Zelle der ersten Zeile einer Abfrage * @param string $sql Die Abfrage * @return mixed Der Wert des Feldes */ public function queryOne($sql) { $row = $this->queryRow($sql); return reset($row); } } /** * @brief MySQL-Layer */ class TMySql extends TDatabase { /** * @brief Konstruktor * @param string $host IP oder Domain des Servers * @param string $name Der Name der Daenbank * @param string $user Berechtigter Benutzer * @param string $passwd Kennwort des Benutzers */ function __construct($host, $name, $user, $passwd) { $this->connect($host, $user, $passwd); $this->select($name); } /** * @brief Destruktor */ function __destruct() { $this->close(); } /** * @brief Datenbankverbindung aufbauen * @param string $host IP oder Domain des Servers * @param string $user Berechtigter Benutzer * @param string $passwd Kennwort des Benutzers */ public function connect($host, $user, $passwd) { $this->close(); $__er = error_reporting(E_ERROR); if (!$this->resource = mysql_connect($host, $user, rawurlencode($passwd))) { error_reporting($__er); throw new EMySql(); } error_reporting($__er); } /** * @brief Datenbankverbindung lösen */ public function close() { if (!$this->resource) return; mysql_close($this->resource); $this->resource = false; } /** * @brief Datenbank auswählen * @param string $name Name der Datenbank */ public function select($name) { if (!mysql_select_db($name, $this->resource)) throw new EMySql(); $this->database = $name; } /** * @brief Datenbankanweisung ausführen * @param string $sql Die Anweisung an die Datenbank * @return mixed */ public function execute($sql) { $this->statements[] = $sql; if (!($result = mysql_unbuffered_query($sql, $this->resource))) throw new EMySql(); $this->count_querys++; return $result; } /** * @brief Datenbankabfrage * @param string $sql Die Anweisung * @param int $offset Relativer Beginn der Ergebnismenge * @param int $limit Maximale Anzahl der Zeilen in der Ergebnismenge * @return TDatabaseResultSet */ public function query($sql, $offset = 0, $limit = -1) { //echo $sql."<br />"; if ($limit != -1) $sql .= sprintf(' LIMIT %d, %d', $offset, $limit); $sql = $this->execute($sql); return new TMySqlResult($sql); } /** * Führt den Query aus und liefert danach die letzte insert ID * @param string $sql Die Anweisung * @return int * @author Tobias Lückel */ public function insert($sql) { $this->execute($sql); return mysql_insert_id(); } /** * Führt den Query aus und liefert danach die Anzahl der betroffenen Datensätze * @param string $sql Die Anweisung * @return int * @author Tobias Lückel */ public function update($sql) { $this->execute($sql); return mysql_affected_rows(); } /** * Gibt die aktuelle Datenbankverbindung zurück * @return MySQL Resource * @author Tobias Lückel */ public function getResource() { return $this->resource; } /** * Liefert die Anzahl der ausgeführten Querys zurück * @return int * @author Tobias Lückel */ public function getAnzahlQuerys() { return $this->count_querys; } /** * Liefert alle ausgeführten Statements zurück * @return string * @author Tobias Lückel */ public function getStatements() { return $this->statements; } /** * Liefert einen escapten String zurück * @return string * @author Tobias Lückel */ public function escapeString($input) { return mysql_real_escape_string($input,$this->getResource()); } } ?>
was haltet ihr von der Datenbankklasse? Habe ich nicht selber geschrieben, nur ein paar Sachen ergänzt. Was verwendet ihr so? Benutzt ihr überhaupt Klassen?
|
|
|
|
|
11.09.2008, 18:13
|
#2 (permalink)
|
|
Pixelschieber
Registriert seit: 18.04.2008
Ort: Detmold
Beiträge: 343
|
Also ich persönlich kann du der Datenbankklasse nichts sagen, da ich für die Daten keine Klasse benutzen. Ich bleibe den normalen Funktionen mysql_query und mysql_fetch_assoc. Ich kann mir auch nicht vorstellen das eine Klasse für MySQL viel Sinn macht.
|
|
|
|
11.09.2008, 19:13
|
#3 (permalink)
|
|
Erfahrener Benutzer
Registriert seit: 19.02.2008
Beiträge: 155
|
Ich muss sagen, dass ich die Klasse für relativ unübersichtlich halte. Meine Klasse:
PHP-Code:
<?
class db {
var $db;
var $num;
var $res;
var $row;
function connect() {
$this->db = mysql_connect(HOST, USER, PWD);
if(mysql_select_db(DB) == 0)
die('<h2>Datenbank nicht zu erreichen!</h2>');
}
function disconnect() {
mysql_close($this->db);
}
function query($query) {
$this->res = mysql_query($query);
return $this->res;
}
function numRows() {
$this->num = mysql_num_rows($this->res);
return $this->num;
}
function fetch() {
$this->row = mysql_fetch_array($this->res);
return $this->row;
}
function row($field) {
return $this->row[$field];
}
function insertID() {
$this->id = mysql_insert_id();
return $this->id;
}
}
?>
@Sebastian: Der sinn is einfach, dass diverse Variaben etc. einfach in der Klasse verschwinden. Beispiel:
PHP-Code:
$db->query("SELECT * FROM `blah`");
while($db->fetch()) {
$foo = $db->row('foo');
$bar = $db->row('bar');
}
Meiner Meinung isses demnach ein Vorteil.
|
|
|
|
11.09.2008, 21:48
|
#4 (permalink)
|
|
Erfahrener Benutzer
Registriert seit: 04.08.2008
Beiträge: 129
|
Bisschen unübersichtlich bei der oben ist glaube ich, dass Fehler geworfen werden, sodass ich darauf eingehen kann und nicht wie bei dir mit dem die die ganze ausführung des skriptes unterbreche.
Aber Datenbankklasse finde ich schon sinnvoll, bei mir eigentlich nicht mehr wegzudenken.
|
|
|
|
|
14.09.2008, 20:01
|
#5 (permalink)
|
|
Pixelschieber
Registriert seit: 18.04.2008
Ort: Detmold
Beiträge: 343
|
Ihr habt mich überzeugt. Dann werde ich mir die Klassen wohl mal angucken und nächsten mal eventuell benutzen.
|
|
|
|
15.09.2008, 09:37
|
#6 (permalink)
|
|
Erfahrener Benutzer
Registriert seit: 04.08.2008
Beiträge: 129
|
Ich habe germerkt, dass ich mir da noch ein bisschen was anderes überlegen muss, da meine Klasse, wo ich sie verwenden will, nicht funktioniert, lokal in XAMPP funktioniert das ganze, aber nicht online. Muss ich mal schauen. Bisschen was eigenes schreiben oder so.
Edit:
Habe jetzt mal ein bisschen was eigenes geschrieben, ohne diese ganzen Exceptions usw., wer braucht sowas schon. Aber das mit dem Iterator musste einfach drin bleiben, dadurch kann ich zum Beispiel einfach sagen:
PHP-Code:
foreach($result as $row) { }
usw.
PHP-Code:
<?php class MegResult implements Iterator { private $numRows = 0; private $pointer = 0; private $rows = array(); function __construct($result) { $rows = array(); $this->numRows = 0; while($row = @mysql_fetch_assoc($result)) { $rows[] = $row; ++ $this->numRows; } $this->rows = $rows; } function rewind() { $this->pointer = 0; } function key() { return $this->pointer; } function current() { if($this->pointer<count($this->rows)) { return $this->rows[$this->pointer]; } return false; } function valid() { return (bool) is_array($this->current()); } function hasNext() { if($this->pointer+1<count($this->rows)) { return true; } return false; } function next() { $this->pointer++; } function get_num_rows() { return $this->numRows; } } class MegDB { private $ressource; private $dbhost; private $dbuser; private $dbpass; private $dbschema; private $dbprefix; private $connected = false; private $statements = array(); private $lastStatement; private $numQuerys = 0; private $numRows = 0; function __construct($dbhost,$dbuser,$dbpass,$dbschema,$dbprefix) { $this->dbhost = $dbhost; $this->dbuser = $dbuser; $this->dbpass = $dbpass; $this->dbschema = $dbschema; $this->dbprefix = $dbprefix; if($this->connect()) { if($this->select()) { return true; } } return false; } function __destruct() { if($this->connected) { mysql_close($this->ressource); } } function connect() { $this->ressource = @mysql_connect($this->dbhost,$this->dbuser,$this->dbpass); if($this->ressource=='') { return false; } return true; } function select() { if(mysql_select_db($this->dbschema,$this->ressource)) { $this->connected = true; return true; } return false; } function execute($sql,$sqltype="select") { $result = mysql_query($sql,$this->ressource); if($result!=false) { array_push($this->statements,array("statement"=>$sql, "erfolg"=>1, "error"=>null)); $this->lastStatement = $this->statements[count($this->statements)-1]; $this->numQuerys++; switch($sqltype) { case "select": $this->numRows = @mysql_num_rows($result); break; case "insert": case "update": case "delete": $this->numRows = @mysql_affected_rows($this->ressource); break; } return $result; } array_push($this->statements,array("statement"=>$sql, "erfolg"=>0, "error"=>mysql_errno().": ".mysql_error())); $this->lastStatement = $this->statements[count($this->statements)-1]; return false; } function query($sql) { if($this->connected) { $result = $this->execute($sql); return new MegResult($result); } return false; } function insert($sql) { if($this->connected) { $result = $this->execute($sql,"insert"); if($result!=false) { return mysql_insert_id($this->ressource); } } return false; } function update($sql) { if($this->connected) { $result = $this->execute($sql,"update"); if($result!=false) { return true; } } return false; } function getRessource() { return $this->ressource; } function countQuerys() { return $this->numQuerys; } function get_num_rows() { return $this->numRows; } function getStatements() { return $this->statements; } function getErrorStatements() { $errorStatements = array(); foreach($this->statements as $statement) { if($statement['erfolg']==0) { array_push($errorStatements,$statement); } } return $errorStatements; } function clearStatements() { $this->statements = array(); $this->lastStatement = NULL; } function getLastStatement() { return $this->lastStatement; } function isConnected() { if($this->connected) { return true; } return false; } function escapeString($input) { return mysql_real_escape_string($input,$this->ressource); } function escapeArray($input) { for($i=0;$i<count($input);$i++) { $input[$i] = $this->escapeString($input[$i]); } return $input; } } ?>
|
|
Geändert von Megger (16.09.2008 um 09:50 Uhr).
|
|
|
17.10.2008, 10:22
|
#7 (permalink)
|
|
Erfahrener Benutzer
Registriert seit: 04.08.2008
Beiträge: 129
|
Habe mal eine Frage, wie macht ihr es wenn ihr Daten in eine Datenbank schreibt und danach mit der ID des Datensatzes weiterarbeiten wollt?
Bei vielen Userzugriffen ist mysql_insert_id wahrscheinlich zu ungenau oder?
|
|
|
|
|
17.10.2008, 16:50
|
#8 (permalink)
|
|
Neuer Benutzer
Registriert seit: 09.10.2008
Beiträge: 12
|
Warum sollte es zu ungenau sein? Wenn du es so schreibst
PHP-Code:
$query = mysql_query("INSERT INTO bla(id,a,b,c) VALUES ( ,d,e,f)"); $mysql_id = mysql_insert_id();
Jetzt musst du nur im kompletten Quelltext auf $mysql_id zugreifen. Dsa sollte eigentlich gehen, da SQL sehr schnell arbeitet.
Ansonsten so:
PHP-Code:
$userid = 123454; $query = mysql_query("INSERT INTO bla(id,a,b,c,userid) VALUES (,d,e,f,".$userid.")"); $row = mysql_fetch_assoc(mysql_query("SELECT id FROM bla WHERE userid=".$userid."")); $mysql_id = $row['id'];
|
|
|
|
|
17.10.2008, 20:14
|
#9 (permalink)
|
|
Erfahrener Benutzer
Registriert seit: 19.02.2008
Beiträge: 155
|
Zitat:
Zitat von Megger
Habe mal eine Frage, wie macht ihr es wenn ihr Daten in eine Datenbank schreibt und danach mit der ID des Datensatzes weiterarbeiten wollt?
Bei vielen Userzugriffen ist mysql_insert_id wahrscheinlich zu ungenau oder?
|
In solchen Fällen arbeitet man ja normalerweise auch mit einer Schleife  Evtl. müsstest du uns dein "Problem" mal schildern.
|
|
|
|
21.10.2008, 09:28
|
#10 (permalink)
|
|
Erfahrener Benutzer
Registriert seit: 04.08.2008
Beiträge: 129
|
Habe gelesen, dass mysql_insert_id sowieso nur gerade für dieses Script arbeitet, selbst wenn ein anderer User genau das gleiche macht, bekommt er eine andere ID, halt die die für ihn gültig ist.
Ich überlege gerade an einem Prinzip, wie ich INSERTs und UPDATEs wieder rückgangig machen kann:
PHP-Code:
$save = $db->savepoint(); $db->query(); $db->insert(); $db->update(); $db->query(); //Bei Fehlern $db->restore($save);
Also im Prinzip so, dass ich einfach einen speicherpunkt anlege und von da an protokolliert er alles mit und baut sozusagen den gegenstring wenn ich es restoren will, also zum beispiel beim update ist ein fehler aufgetreten, nun muss der User von vorne anfangen und das insert soll rückgangig gemacht werden, so kann man einfach das restore ausführen und alles ist wieder so wie zu dem zeitpunkt als man den savepunkt angelegt hat, allerdings betrifft das nur eigene Sachen und nicht die von anderen usern
|
|
|
|
|
| Themen-Optionen |
|
|
| Ansicht |
Linear-Darstellung
|
Forumregeln
|
|
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
|
|
|
Alle Zeitangaben in WEZ +2. Es ist jetzt 20:46 Uhr.
| |
| |