Der Name DatabaseConnector ist von mir gewählt.
Es soll eine Klasse darstellen, die über eine
Fabrikmethode eine den Parametern entsprechendes Objekt erzeugt.
PHP-Code:
<?php
////////////////////////////////////////////////////////////////////////////////////////////////////
require_once S_INCLUDE . 'functions/parseDSN.php';
////////////////////////////////////////////////////////////////////////////////////////////////////
define('DATABASECONNECTOR_FETCHTYPE_ASSOC', 1);
define('DATABASECONNECTOR_FETCHTYPE_ARRAY', 2);
define('DATABASECONNECTOR_FETCHTYPE_OBJECT', 3);
////////////////////////////////////////////////////////////////////////////////////////////////////
class DatabaseConnector
{
protected $hostname;
protected $username;
protected $password;
protected $connected = false;
protected $database;
protected $selected = false;
protected $fetchType = DATABASECONNECTOR_FETCHTYPE_OBJECT;
protected $queries = array();
public static function factory($dsn)
{
$config = parseDSN($dsn);
switch ($config['phptype']) {
case 'mysql':
require_once sprintf('%s/DatabaseConnector_MySQL.php', dirname(__FILE__));
$db = new DatabaseConnector_MySQL();
$db->connect($config['hostspec'], $config['username'], $config['password']);
$db->selectDB($config['database']);
return $db;
default:
}
return false;
}
public function isConnected()
{
return (bool)$this->connected;
}
public function debug()
{
echo "\n\nDatabase Debug: <pre>", print_r($this, true), "</pre>\n\n";
}
public function __destruct()
{
$this->close();
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
?>
(parseDSN() ist übrigens von PEAR_DB kopiert, ich hoffe das ist erlaubt)
Momentan macht sie wenig Sinn, da es nur eine Möglichkeit gibt: MySQL.
Theoretisch könnten hier aber auch andere Datenbanken angesprochen werden, PostgreSQL, DB2 und was es noch so alles gibt.
DatabaseConnector_MySQL() kann nichts, außer die mysql_*() Funktionen zur Verfügung stellen und die Queries loggen. Aber das ist ja schonmal etwas, zum Debuggen zB ganz hilfreich.
Ob du das ganze so übernehmen möchtest musst du entscheiden. Mit nur einer Datenbank-Klasse MySQL bringt es zunächst keinen Vorteil, wäre aber erweiterbar. Die Vorteile müssen aber verstanden sein, sonst macht es wenig Sinn.
Meine DatabaseConnector_MySQL.php sieht dann so aus:
PHP-Code:
<?php
////////////////////////////////////////////////////////////////////////////////////////////////////
require_once sprintf('%s/DatabaseConnector.php', dirname(__FILE__));
////////////////////////////////////////////////////////////////////////////////////////////////////
class DatabaseConnector_MySQL extends DatabaseConnector
{
public function connect($hostname, $username, $password)
{
// set variables
$this->hostname = $hostname;
$this->username = $username;
$this->password = $password;
// connect..
$this->connected = @mysql_connect($this->hostname, $this->username, $this->password);
// log & error
// ..
// return
return $this->connected;
}
public function selectDB($database)
{
// set variable
$this->database = $database;
// select database
$this->selected = @mysql_select_db($this->database);
// log & error
// ..
// return
return $this->selected;
}
public function query($sql)
{
// validate arguments
if (func_num_args() > 1) {
$args = func_get_args();
array_shift($args);
$sql = vsprintf($sql, array_map(array($this, 'escape'), $args));
}
// do your job
$res = @mysql_query($sql, $this->connected);
// log & error
$this->queries[] = $sql;
// return
return $res;
}
public function fetch($res, $type = null)
{
// validate type
if (!isset($type) || !$this->isFetchType($type))
$type = $this->fetchType;
// log & error
// ..
// do your job
$row = false;
switch ($type) {
case DATABASEMANAGER_FETCHTYPE_ASSOC:
$row = $this->fetchAssoc($res);
break;
case DATABASEMANAGER_FETCHTYPE_ARRAY:
$row = $this->fetchArray($res);
break;
case DATABASEMANAGER_FETCHTYPE_OBJECT:
$row = $this->fetchObject($res);
break;
}
// return
return $row;
}
public function fetchAssoc($res)
{
// do your job
$row = @mysql_fetch_assoc($res);
// log & error
// ..
// return
return $row;
}
public function fetchArray($res)
{
// do your job
$row = @mysql_fetch_array($res);
// log & error
// ..
// return
return $row;
}
public function fetchObject($res)
{
// do your job
$row = @mysql_fetch_object($res);
// log & error
// ..
// return
return $row;
}
public function close()
{
// do your job
if (@mysql_close($this->connected))
$this->connected = false;
// log & error
// ..
// return
return $this->connected;
}
private function escape($string)
{
if (!get_magic_quotes_gpc())
$input = mysql_real_escape_string($string);
return $string;
}
private function isFetchType($type)
{
switch ($type) {
case DATABASEMANAGER_FETCHTYPE_ASSOC:
case DATABASEMANAGER_FETCHTYPE_ARRAY:
case DATABASEMANAGER_FETCHTYPE_OBJECT:
return true;
}
return false;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
?>
Wie du siehst existiert hier auch nichteinmal log & error. Ich wollte schnell vorankommen und an einem anderen Problem arbeiten.
Zu deiner 2. Frage: Was ist eine
Referenz:
PHP-Code:
<?php
function manipuliere1(&$x) { // beachte das &
$x++;
print "manipuliere1: $x
\n";
}
function manipuliere2($x) {
$x++;
print "manipuliere2: $x
\n";
}
$x = 5;
print "vorher: $x
\n";
manipuliere1($x); // Ausgabe 6, $x wurde "global" um 1 ($x++) erhöht
manipuliere2($x); // Ausgabe 7, $x wurde nur in der Funktion erhöht
print "nachher: $x"; // Ausgabe 6, denn manipuliere2() hat nur mit einer Kopie hantiert
?>
http://de3.php.net/references