Webstatt.org - Community seit 2006 - 2012 (2024?)

Datenbank objekt orientiert anbinden

user-240
08.03.2006 15:08

Hallo,

irgendwie funktioniert da was nicht. Immer kommt dieser Fehler:


Parse error: syntax error, unexpected T_RETURN in C:\Programme\xampp\htdocs\test\database.php on line 28



<?php

class db {

var $dbhost = "";
var $dbuser = "";
var $dbpw = "";
var $db = "";

function connect($dbhost, $dbuser, $dbpw) {
if (! $linkid = mysql_connect("$dbhost", "$dbuser", "$dbpw"zwinkern){
echo "<p>Die Verbindung zu $dbhost konnte nicht hergestellt werden.</p>";
exit;
}
return $linkid;
}

function select($db) {
if (! $db = mysql_select_db($db)){
echo "<p>Auswahl der Datenbank zur Zeit nicht moeglich:" .mysql_error()."</p>" ;
exit;
}
return $db;
}

function query($db, $sql) {
$res = mysql_query($sql)
return $res;
}


}


?>


Kann mir da jemand weiterhelfen?

gruß

mar123

user-210
08.03.2006 15:11

Dir fehlte ein Semikolon.



function query($db, $sql) {
$res = mysql_query($sql);
return $res;
}

Sie haben soeben die Position Ihres Mauszeigers auf dem Monitor verändert. Bitte starten sie Windows neu damit die Änderungen wirksam werden.
Avatar user-253
08.03.2006 17:37

Ich freue mich immer wenn objektorientiert programmiert wird. Falls es jemanden interessiert hier eine schnell runtergeschriebene PHP4 MySQL Klasse, die als Ergebnis ein eigenes Ergebnis Objekt zurück gibt.

class webstatt_db {

var $db_connection = false;
var $lib = false;

function webstatt_db(&$lib,$hostname,$username,$password,$database) {
$this->_init(&$lib,$hostname,$username,$password,$database);
}

function _init(&$lib,$hostname,$username,$password,$database) {
$this->db_connection = mysql_connect($hostname,$username,$password);
mysql_select_db($database,$this->db_connection);
$this->lib = &$lib;

return true;
}

/*************/
/* INTERFACE */
/*************/

function query($querystring) {
$query = @mysql_query($querystring,$this->db_connection);
if(!$query) {
$query = false;
}

$factory = $this->lib->get_factory();
return $factory->create_query($query);
}

function singlequery($querystring) {
$query = @mysql_query($querystring,$this->db_connection);
if(!$query) {
$query = false;
}

$factory = $this->lib->get_factory();
$query = $factory->create_query($query);
return $query->next('array'zwinkern;
}

function close() {
return mysql_close($this->db_connection);
}

}

class webstatt_query {

var $query = false;

function webstatt_query(&$lib,$query) {
$this->_init(&$lib,$query);
}

function _init(&$lib,$query) {
$this->lib = &$lib;
$this->query = $query;

return true;
}

/*************/
/* INTERFACE */
/*************/

function next($type='object'zwinkern {
$row = false;
if($this->query) {
switch($type) {
case 'object': $row = mysql_fetch_object($this->query);
break;
case 'assoc': $row = mysql_fetch_assoc($this->query);
break;
case 'array': $row = mysql_fetch_array($this->query);
}
}
return $row;
}

}


// edit

Highlighting vergessen

Avatar user-300
08.03.2006 18:39

Hier auch meine kleine (und noch im Aufbau befindliche) MySQLi Klasse.
Verbesserungsvorschläge sind erwünscht frech

Die Klasse ist im Moment noch mit mehr oder minder geistreichen Kommentaren versehen. Ich sollte Mal wieder etwas "ausmisten" und aufräumen...

<?php

// Klasse instantiieren
$mysqli = new Mysqli_klasse;
$mysqli->connect('localhost', 'benutzer', 'passwort', 'datenbank'zwinkern;



// Klasse definieren
class Mysqli_klasse
{


// =========================================================================
// INSTANZVARIABLEN DEFINIEREN
// =========================================================================

private $link = NULL;
private $result = NULL;


// =========================================================================
// MYSQL VERBINDUNG HERSTELLEN
// -
// - erstellt Verbdindung zur MySQL Datenbank
// =========================================================================

public function connect($host, $benutzer, $pw, $db)
{
// nicht MYSQLI_REPORT_ALL oder *_all, sonst: No index used in query/prepared statement
mysqli_report(MYSQLI_REPORT_ERROR);
$this->link = mysqli_connect($host, $benutzer, $pw, $db) or $this->fehler();
return TRUE;
}


// =========================================================================
// DESTRUKTOR: MYSQL VERBINDUNG UNTERBRECHEN
// =========================================================================

// public, so kann die Methode auch manuell aufgerufen werden
public function __destruct()
{
if (is_object($this->link)) {
mysqli_close($this->link);
}
if (is_object($this->result)) {
mysqli_free_result($this->result);
return true;
}

mysqli_report(MYSQLI_REPORT_OFF);

/* Be very careful using this function - it's a per-process setting. If your server is set up to reuse a single PHP process for multiple requests, that means the last setting of this function in any script will affect all other scripts using mysqli. To be safe always call <? mysqli_report(MYSQLI_REPORT_OFF) ?> at the end of a script. The CGI version of PHP is probably safe from this. (Tested using PHP 5.0.5, Apache 2 SAPI module) */

return TRUE;
}


// =========================================================================
// MYSQL ABFRAGE DURCHFUEHREN
// =========================================================================

public function query($query)
{
if (is_object($this->link)) {

// mysqli_real_escape_string() fuer alle zusaetzlichen Parameter
if (func_num_args() > 1) {
$parameter = func_get_args();
unset($parameter[0]); // Query loeschen
$query = vsprintf($query, array_map(array(get_class($this), 'escape_string'zwinkern, $parameter));
}

$this->result = mysqli_query($this->link, $query) or $this->fehler();
return $this->result;
}
}


// =========================================================================
// ZEILE AUS DATENBANK AUSLESEN
// =========================================================================

public function fetch_assoc($query)
{
$row = mysqli_fetch_assoc($query);

if (is_array($row)) {
return $row;
}
else {
return FALSE;
}
}


// =========================================================================
// ABFRAGE PARAMETER ESCAPEN
// =========================================================================

public function escape_string($var)
{
return mysqli_real_escape_string($this->link, $var);
}


// =========================================================================
// FEHLERMELDUNGEN ANZEIGEN LASSEN
// =========================================================================

private function fehler()
{
$meldung = '<p>--<br /><strong>Es ist ein Datenbank Fehler aufgetreten!</strong>';
if ($_SERVER['HTTP_HOST'] == 'localhost'zwinkern {
$meldung .= '<br />' . mysqli_error($this->link);
}
$meldung .= '<br />--</p>';
die($meldung);
}


// =========================================================================
// SPEICHER FREIGEBEN
// =========================================================================

public function free_result($obj)
{
mysqli_free_result($obj);
return TRUE;
}
}


?>

Avatar user-255
08.03.2006 18:43

Original von user-300
Verbesserungsvorschläge sind erwünscht frech

Na gut. zwinkern
Den Desktruktor würd ich nicht ins Interface packen, lieber eine Funktion für die Verbindungstrennung definieren (public) und diese dann im Desktuktor aufrufen.

Those who can, do. Those who can't, teach. # Musik gehört dem Volk! # last.fm
Avatar user-300
09.03.2006 16:34

Hm. Warum meinst du? zwinkern
Manuell aufrufen tue ich ihn im Moment nicht. Er ist nur 'public' um sich diese Möglichkeit offenzuhalten.

Avatar user-253
09.03.2006 18:04

Der Destruktor sollte umbedingt public sein.
Wäre er private/protected könnte er bei unset nicht aufgerufen werden - und das ist ja gerade der Sinn lächeln

Ob man die Verbindungstrennung in eine extra Funktion packt (sinnvollerweise dann als non-public), darüber kann man streiten. Ich persönlich würde jeden logischen Schritt ausgliedern, möglicherweise wird der Destructor ja irgendwann erweitert oder er-erbt, dann wäre eine Methode schöner).

Ansonsten schaue ich mir morgen die Klasse einmal ausführlich an, aber auf den ersten Blick sieht es sehr gut aus.

Avatar user-300
09.03.2006 18:11

Original von user-251el
Der Destruktor sollte umbedingt public sein.
Wäre er private/protected könnte er bei unset nicht aufgerufen werden - und das ist ja gerade der Sinn lächeln

Ob man die Verbindungstrennung in eine extra Funktion packt (sinnvollerweise dann als non-public), darüber kann man streiten. Ich persönlich würde jeden logischen Schritt ausgliedern, möglicherweise wird der Destructor ja irgendwann erweitert oder er-erbt, dann wäre eine Methode schöner).

Ansonsten schaue ich mir morgen die Klasse einmal ausführlich an, aber auf den ersten Blick sieht es sehr gut aus.


OK, danke für deine Tipps. Mehr Feedback ist gerne erwünscht lächeln

Avatar user-300
12.03.2006 17:50

Original von user-251el
Ansonsten schaue ich mir morgen die Klasse einmal ausführlich an, aber auf den ersten Blick sieht es sehr gut aus.


Michael, bist du schon dazu gekommen? lächeln

Avatar user-253
21.03.2006 16:47

So jetzt kam ich dazu:

1) Ich würde einen Konstruktor definiere, der dann intern connect aufruft.
2) In der Fehler Methode lieber nur einen String zurückgeben. Das Programm sollte entscheiden, was mit dem Fehler passiert (also die(..) oder eine andere Fehlerbehandlung). Hier sollte auch kein HTML Code sondern nur die Meldung zurückgegeben werden.
3) Der destructor sollte free_result benutzen
4) Die Query Methode liefert ein Objekt zurück, dass von dem Programm wieder an die Klasse übergeben werden muss, beispielsweise bei fetch_assoc. Schöner wäre es wenn der User diesen Rückgabewert nicht selbst verwalten müsste. Entweder könntest du ihn in einem Klassenattribut speichern (dann kann die Klasse natürlich immer nur ein Query) oder du kapselst den Rückgabewert wieder in einem Objekt, das dann die dazugehörigen Zugriffsfunktionen hat (fetch_assoc usw)
5) Die Query Method nimmt beliebig viele Parameter entgegen, das ist unübersichtlich. Besser wäre es die zusätzlichen Parameter als Array zu übergeben, der ansonsten leer bleibt. Es ist dann viel leichter zu verstehen

So das war es erst einmal. Ich poste anschließend mal eine halb fertige PHP5 MySQL Klasse, die ich einmal anfing. Da das Projekt nie entstand ist sie weder komplett noch getestet. Vielleicht findest du noch ein paar Anregungen.

Avatar user-253
21.03.2006 16:52

So hier die angesprochene Klasse.
Ein paar Anmerkungen:

- die Klasse versucht DBX zu verwenden, nur wenn das nicht möglich ist die normalen MySQL Funktionen. Das Interface bleibt dabei gleich
- Die Ergebnisse werden wieder als eigenes Objekt zurückgegeben
- Die Klasse berechnet sinnlose Statistiken (also Anzahl, Dauer, Durchschnittsdauer). Dies sollte damals so sein, die Infos sind natürlich genauso so sinnlos wie ein öffentlicher Counter
- Es werden die __get/__set Methoden benutzt um eine komfortablere Bedienung zu ermöglichen und dynamische Attribute zu realisieren

<?php

class mysql {

protected $hConnectionId = false;
public $boError = false;
public $iQueries = 0;
public $fQuerytime = 0.0;
static $iConnections = 0;
protected $boDBX = false;

public function __construct($a_stHostname,$a_stUsername,$a_stPassword,$a_stDatabase) {
$this->boDBX = extension_loaded('dbx'zwinkern;
// disable dbx
$this->boDBX = false;
if($this->boDBX) {
if($this->hConnectionId = @dbx_connect('mysql',$a_stHostname,$a_stDatabase,$a_stUsername,$a_stPassword,DBX_PERSISTENT)) {
// increase active connections
++self::$iConnections;
} else {
// connection failed
$this->boError = true;
throw new Exception('connection failed'zwinkern;
return false;
} // end else
} else {
if(($this->hConnectionId = @mysql_connect($a_stHostname,$a_stUsername,$a_stPassword)) && (mysql_select_db($a_stDatabase,$this->hConnectionId))) {
// increase active connections
++self::$iConnections;
} else {
// connection failed
$this->boError = true;
throw new Exception('connection failed'zwinkern;
return false;
} // end else
} // end else
return true;
} // end constructor

public function __destruct() {
// close connection if any exists
if(($this->hConnectionId) && ($this->boDBXExtensionEnabled)) {
dbx_close($this->hConnectionId);
} elseif($this->hConnectionId) {
@mysql_close($this->hConnectionId);
} // end elseif
return true;
} // end destructor

// abstract data
// averagequerytime
// querytime
// querycount
// activeconnections
public function __get($a_stName) {
switch(strtolower($a_stName)) {
case 'averagequerytime': return $this->iQueryCount==0 ? 0 : number_format($this->fQueryTime/$this->iQueryCount,4);
break;
case 'querytime': return number_format($this->fQueryTime,2);
break;
case 'querycount': return $this->iQueryCount;
break;
case 'activeconnections': return self::$iActiveConnections;
break;
default: return false;
break;
} // end switch
} // end get

final public function isConnected() {
return (($this->hConnectionId) && (!$this->boError)) ? true : false;
} // end function isConnected

/*************/
/* INTERFACE */
/*************/

public function query($a_stQuery) {

// is there an active connection
if(($this->hConnectionId) && (!$this->boError)) {
// error handling
try {
++$this->iQueryCount;
// timer
$aMicrotime = explode(' ', microtime());
$fQueryStart = $aMicrotime[1] + $aMicrotime[0];
// fire statement through congruous extension
$oQuery = $this->boDBX ? new DBXResult(dbx_query($this->hConnectionId,$a_stQuery,DBX_RESULT_ASSOC)) : new MySQLResult(mysql_query($a_stQuery,$this->hConnectionId));
$aMicrotime = explode(' ', microtime());
$this->fQuerytime += $aMicrotime[1] + $aMicrotime[0] - $fQueryStart;
// rückgabe des objekts mit allen daten und zugriffsfunktionen zum arbeiten mit dem query
return $oQuery;
} // end try
// error catching
catch(Exception $oException) {
return false;
} // end catch
} else {
// no active connection
return false;
} // end else
} // end function query

} // end class mysql

// abstract parent class of both result dataobjects
abstract class dbresult {

protected $mQuery = false;
public $boError = false;
public $iSize = 0;
protected $iPosition = 0;

public function __construct($a_QueryResult) {
// successful query
if($a_QueryResult) {
$this->mQuery = $a_QueryResult;
// ... und ermitteln der grösse
$this->iSize = $this->_getSize();
return true;
} else {
// wenn nicht
$this->boError = true;
// eine fehlermeldung erzeugen
throw new Exception('invalid query'zwinkern;
return false;
} // end else
} // end constructor

// abstract data
// size
public function __get($a_stVariablenName) {
switch(strtolower($a_stVariablenName)) {
case 'size': return $this->iResultSize;
break;
default: return false;
break;
} // end switch
} // end get

// declare function prototypes
abstract protected function _getSize();
abstract public function nextResult();
abstract public function previousResult();

} // end class dbresult

// DBX Resultset
class DBXResult extends dbresult {

protected function _getSize() {
return sizeof($this->mQuery->data);
} // end function _getSize

public function nextResult() {
if((!$this->boError) && ($this->iPosition<$this->iSize)) {
// increase position
++$this->iPosition;
// return fitting dataset
return $this->mQuery->data[$this->iPosition-1];
} else {
return false;
} // end else
} // end function nextResult

public function previousResult() {
if((!$this->boError) && ($this->iPosition>0)) {
// decrease position
--$this->iPosition;
// and return the dataset
return $this->mQuery->data[$this->iPosition];
} else {
return false;
} // end else
} // end function previousResult

} // end class DBXResult

// MySQL Resultset
class MySQLResult extends dbresult {

protected function _getSize() {
$iSize = 0;
if(!$iSize = @mysql_num_rows($this->mQuery)) {
$iSize = @mysql_affected_rows($this->mQuery);
} // end if
// its necessary as $iSize will be false instead of 0 with an empty query
return $iSize ? $iSize : 0;
} // end function _getSize

public function nextResult() {
if((!$this->boError) && ($this->iPosition<$this->iSize)) {
++$this->iPosition;
return mysql_fetch_assoc($this->mQuery);
} else {
return false;
} // end else
} // end function nextResult

public function previousResult() {
if((!$this->boError) && ($this->iPosition>0) && ($this->iSize!=0)) {
// position um 1 zurücksetzen
--$this->iPosition;
// den zeiger des mysql results auf diese position setzen
mysql_data_seek($this->mQuery,$this->iPosition);
// und ergebnis als assoziatives array zurückgeben
return mysql_fetch_assoc($this->mQuery);
// ansonsten false
} else {
return false;
} // end else
} // end function previousResult

} // end class MySQLResult

?>

Avatar user-118
23.04.2007 19:19

Gefahr laufend einen aufn Deckel zu bekommen weil ich teils kopiert habe stelle ich mal das vor, was ich für die MySQL-Anbindung benutze...

Wann kann man da noch verbessern ?

<?php
/****************/
/* MySQL Klasse */
/****************/
class MySQL {

private $link = NULL;
private $lastres = NULL;
private $lastquery = NULL;
private $connected = false;

public function __construct($host, $user, $pass, $db, $prefix) {
$this->connect($host, $user, $pass, $db);
$this->db = $db;
$this->prefix = $prefix;
}

public function connect($host, $user, $pass, $db) {
if (!$this->connected) {
$this->link = @mysql_connect($host, $user, $pass);
}
if (!$this-link) {
$this->error();
}
$select_db = @mysql_select_db($db, $this->link);
if (!$select_db) {
$this->error();
}
$this->connected = true;
return true;
}

public function query($query, $values = array()) {
if (func_num_args() > 3) {
trigger_error("Zu viele Arrayelemente."zwinkern;
}
$oquery = $query;
$replace = array('%prefix%' => mysql_real_escape_string($this->prefix));
foreach ($values as $search => $content) {
$replace['%'.$search.'%'] = mysql_real_escape_string($content, $this->link);
}
$query = strtr($query, $replace);
// set the latest query
$this->lastquery = $query;
if (!($this->lastres = mysql_query($query, $this->link))) {
$this->error();
exit;
}
return $this->lastres;
}

public function next($type='object'zwinkern {
$row = false;
if($this->lastres) {
switch($type) {
case 'object': $row = mysql_fetch_object($this->lastres);
break;
case 'assoc': $row = mysql_fetch_assoc($this->lastres);
break;
case 'array': $row = mysql_fetch_array($this->lastres);
break;
}
}
return $row;
}

public function get_row() {
return mysql_fetch_row($this->lastres);
}

public function num_rows() {
return mysql_num_rows($this->lastres);
}

public function insert_id() {
return mysql_insert_id();
}

public function escape_string($string) {
return mysql_real_escape_string($this->link, $string);
}

public function get_databasesize($rounding, $unit) {
$this->query("SHOW TABLE STATUS FROM `".$this->db."`"zwinkern;
while ($result = $this->next($type='array'zwinkern) {
$data[] = $result;
}
$db_size = 0;
for($i = 0; $i < count($data); $i++) {
$db_size += $data[$i]["Data_length"] + $data[$i]["Index_length"];
}
switch($unit) {
case 'gb':
$factor = "1073741824";
break;
case 'mb':
$factor = "1048576";
break;
case 'kb':
$factor = "1024";
break;
}
if (empty($factor))
return $db_size;
else
return round(($db_size / $factor), $rounding);
}

public function get_tablecounts() {
$this->query("SHOW TABLE STATUS FROM `".$this->db."`"zwinkern;
while ($result = $this->next($type='array'zwinkern) {
$data[] = $result;
}
return count($data);
}

private function error() {
$message = '<p>--<br /><strong>Es ist ein Datenbankfehler aufgetreten!</strong>';
if ($_SERVER['HTTP_HOST'] == '127.0.0.1'zwinkern {
$message .= '<br />' . mysql_error();
}
$message .= '<br />--</p>';
die($message);
}

public function __destruct() {
if (is_object($this->link)) {
@mysql_close($this->link);
unset($this->link);
$this->connected = false;
}
if (is_object($this->res)) {
mysql_free_result($this->res);
return true;
}
}
}
?>


Also ich weiß, dass ich was kopiert habe von user-251el, Sili und die Queryfunktion ausm Hesasys...

Achja: ähhh falls sich die betreffenden Leute gestört fühlen, dass ich mir was raus kopiert haben sollen sie es doch bitte eben sagen, danke.

Ich brauche keine Signatur
Avatar user-253
23.04.2007 19:59

Wie schon in ICQ gesagt ist es für mich gar kein Problem, der Code wird hier ja ausgetauscht, damit er weiterverwendet wird.

Zu deiner Klasse:
1) Ich pers. mag keine HTML Ausgabe (beispielsweise bei error). Mir ist klar, dass es ohne weitere Klassen drum herum nicht anders geht, aber schöner wird es so dennoch nicht
2) Anstelle von num_rows würde ich eine Methode implementieren, die die Anzahl der Datensätze zurückgibt und dabei automatisch die richtige Funktion (num_rows oder affected_rows) benutzt)
3) Anstelle des mysql_query Rückgabewertes würde ich ein neues Objekt (wieder so eine Kapselung nur als Zugriff auf die neue Ressource) zurückgeben.

Avatar user-300
23.04.2007 20:18

Original von user-118
Also ich weiß, dass ich was kopiert habe von user-251el, Sili und die Queryfunktion ausm Hesasys...

Achja: ähhh falls sich die betreffenden Leute gestört fühlen, dass ich mir was raus kopiert haben sollen sie es doch bitte eben sagen, danke.


Kein Problem lächeln
Ich wollte meine Klasse sowieso auch mal etwas erweitern und deine Ansätze werde ich mir sicherlich auch ansehen.

Avatar user-300
14.07.2007 11:44

Meine etwas überarbeitete MySQLi Klasse lächeln
Aber viele Erweiterungen sind noch experimentell und kaum getestet. Auch bezüglich Geschwindigkeit habe ich noch gar keine Tests gemacht.

Kritik gerne zwinkern



<?php



// Klasse instantiieren und mit DB verbinden
$db = new mysqli_class('localhost', 'benutzer', 'passwort', 'tabelle'zwinkern;



// Klasse definieren
class mysqli_class
{


// =========================================================================
// ATTRIBUTE DEKLARIEREN
// =========================================================================

private $link = NULL; // von mysqli_connect
private $result = NULL; // von mysqli_query

//private $query = NULL;



// =========================================================================
// KONSTRUKTOR
// =========================================================================

public function __construct($host, $benutzer, $pw, $db)
{
// MySQLi Report für lokale Anwendungen
if ($_SERVER['HTTP_HOST'] == 'localhost'zwinkern {
mysqli_report(MYSQLI_REPORT_ERROR);
// nicht MYSQLI_REPORT_ALL, sonst: No index used in query/prepared statement
// mysqli_report(MYSQLI_REPORT_ALL);
}

// Mit Datenbank verbinden
$this->connect($host, $benutzer, $pw, $db);

return TRUE;
}



// =========================================================================
// MYSQLI VERBINDUNG HERSTELLEN
// =========================================================================

public function connect($host, $benutzer, $pw, $db)
{
$this->link = mysqli_connect($host, $benutzer, $pw, $db) or $this->fehler();
return TRUE;
}



// =========================================================================
// DESTRUKTOR: MYSQL VERBINDUNG SCHLIESSEN
// =========================================================================

// public! Sonst kann sie bei unset() nicht aufgerufen werden
public function __destruct()
{
if (is_object($this->link)) {
mysqli_close($this->link);
}
if (is_object($this->result)) {
$this->free_result($this->result);
}

// Immer ausschalten, wird ansonsten für ALLE MySQLi Anwendungen verwendet!
// http://ch2.php.net/manual/de/function.mysqli-report.php#58489
mysqli_report(MYSQLI_REPORT_OFF);

return TRUE;
}



// =========================================================================
// MYSQL ABFRAGE DURCHFUEHREN
// =========================================================================

public function query($query, $a_parameter = FALSE)
{
if (is_object($this->link)) {

// mysqli_real_escape_string() fuer alle zusaetzlichen Parameter
if (is_array($a_parameter)) {
$query = vsprintf($query, array_map(array($this, 'escape_string'zwinkern, $a_parameter));
}

//echo '<p>' . $query . '</p>'; // nur zu Testzwecken
$this->result = mysqli_query($this->link, $query) or $this->fehler();
return $this->result;
}

return FALSE;
}



// =========================================================================
// WERTE AUS DATENBANK AUSLESEN
// =========================================================================

public function fetch($result = FALSE)
{
return mysqli_fetch_assoc($this->get_result($result));
}

public function fetch_extract($result = FALSE, $prefix = 'row_'zwinkern
{
$row = $this->fetch($result);

if (!$row or !is_array($row)) {
return FALSE;
}

foreach ($row as $key => $var) {
$GLOBALS[$prefix . $key] = $var;
}

return TRUE;
}


// -------------------------------------------------------------------------
// Gibt die erste (oder einzige) Zeile als assoziatives Array zurueck
// -------------------------------------------------------------------------

public function fetch_single_row($result = FALSE)
{
$result = $this->get_result($result);

// MUSS NOCH GETESTET WERDEN!!
if ($this->num_rows($result) > 1) {
mysqli_data_seek($result, 0);
}

return mysqli_fetch_array($result);
}

public function num_rows($result = FALSE)
{
return mysqli_num_rows($this->get_result($result));
}

// -------------------------------------------------------------------------
// Gibt einen einzelnen Wert zurueck
// -------------------------------------------------------------------------

public function fetch_value($result = FALSE)
{
$result = $this->get_result($result);
return false;
}



// =========================================================================
// GIBT EIGENES ODER VORHANDENES RESULT ZURÜCK
// =========================================================================

private function get_result($result = FALSE)
{
if (!$result or !is_object($result)) {
return $this->result;
}

if (is_string($result)) {
// Kann auch als query benutzt werden, z.B.
// echo $db->num_rows('SELECT ... FROM ...'zwinkern;
$this->query($result);
return $this->result;
}

return $result;
}



// =========================================================================
// KLEINE METHODEN
// =========================================================================

// =========================================================================
// ANDERE DATENBANK AUSWAEHLEN
// =========================================================================

public function select_db($db)
{
return mysqli_select_db($this->link, $db) or $this->fehler();
}



// =========================================================================
// ABFRAGE PARAMETER ESCAPEN
// =========================================================================

private function escape_string($var)
{
return mysqli_real_escape_string($this->link, $var);
}



// =========================================================================
// FEHLERMELDUNGEN ANZEIGEN LASSEN
// =========================================================================

private function fehler()
{
$meldung = '<p>--<br /><strong>Es ist ein Datenbank Fehler aufgetreten!</strong>';
if ($_SERVER['HTTP_HOST'] == 'localhost'zwinkern {
$meldung .= '<br />' . mysqli_error($this->link);
}
$meldung .= '<br />--</p>';
die($meldung);
}



// =========================================================================
// SPEICHER FREIGEBEN
// =========================================================================

public function free_result($obj)
{
mysqli_free_result($obj);
return true;
}
}





/*


================================================================================
VERBESSERUNGSVORSCHLÄGE
================================================================================

2) In der Fehler Methode lieber nur einen String zurückgeben. Das Programm sollte entscheiden, was mit dem Fehler passiert (also die(..) oder eine andere Fehlerbehandlung). Hier sollte auch kein HTML Code sondern nur die Meldung zurückgegeben werden.


## FERTIG ##
1) Ich würde einen Konstruktor definiere, der dann intern connect aufruft.
3) Der destructor sollte free_result benutzen
5) Die Query Method nimmt beliebig viele Parameter entgegen, das ist unübersichtlich. Besser wäre es die zusätzlichen Parameter als Array zu übergeben, der ansonsten leer bleibt. Es ist dann viel leichter zu verstehen
4) Die Query Methode liefert ein Objekt zurück, dass von dem Programm wieder an die Klasse übergeben werden muss, beispielsweise bei fetch_assoc. Schöner wäre es wenn der User diesen Rückgabewert nicht selbst verwalten müsste. Entweder könntest du ihn in einem Klassenattribut speichern (dann kann die Klasse natürlich immer nur ein Query) oder du kapselst den Rückgabewert wieder in einem Objekt, das dann die dazugehörigen Zugriffsfunktionen hat (fetch_assoc usw)




================================================================================
VERAENDERUNG
================================================================================

* $query = vsprintf($query, array_map(array(__CLASS__, 'escape_string'zwinkern, $a_parameter));
in
$query = vsprintf($query, array_map(array($this, 'escape_string'zwinkern, $a_parameter));
geaendert, ansonsten Strict Error (PHP 5.1.2).


*/



?>



Wie man sieht das ist das ganze noch etwas Gettho zwinkern
Vieles ist noch nicht (so) eingebaut, wie ich das gerne hätte und wie gesagt, vieles ist noch experimentell.

Vorschläge? lächeln

user-343
14.07.2007 15:10

Wo ist der Vorteil gegenüber der eigentlichen MySQLi-Klasse? Ich seh nur Nachteile Fettes Grinsen Gut, ist ja auch noch experimentell.

Avatar user-300
15.07.2007 00:41

Original von user-343
Wo ist der Vorteil gegenüber der eigentlichen MySQLi-Klasse? Ich seh nur Nachteile Fettes Grinsen Gut, ist ja auch noch experimentell.


Was siehst du denn als Nachteil?
Als Vorteil sehe ich, dass du nicht mehr immer alle Parameter der Funktionen angeben musst und nun viel einfacher an die Resultate einer Datenbankabfrage rankommst usw. lächeln
Bsp. gefällig?

user-343
15.07.2007 13:12

Prepared-Statements gehen damit nicht. ^^
Als Wrapper, okay. Da ist es natürlich ein Vorteil, ne Abstraktionsschicht zu erstellen. Wobei ich mich frage, warum man nicht einfach PDO nimmt.

$db = new MySQLi($host, $name, $pass, $table);
$res = $db->Query('[...]'zwinkern;
if($res->num_rows > 0) {
while($row = $res->Fetch_Assoc()) {
$res->Query('UPDATE [...]'zwinkern;
}
}


Wie würde das mit deiner Klasse aussehen?

Avatar user-300
15.07.2007 19:47

Nunja, viel einfacher geht das bei meiner Klasse auch nicht...

$db = new mysqli_class($host, $name, $pass, $table);
$db->query('[...]'zwinkern;
if ($db->num_rows() > 0) {
while ($db->fetch_extract()) {
$db->query('UPDATE [...]'zwinkern;
}
}


Die Vorteile liegen wohl eher bei der automatischen Überprüfung der Variablen in einem Query, dem Abfangen von etwaigen Fehlermeldungen, einfacherem Auslesen der Datenbank (fetch_extract()) und noch einige andere Sachen zwinkern