Dlaczego miałoby się nie udać?
<?php
class DB
{
public $connected = false;
protected $prefix = 'abc_';
public function __construct( )
{
echo "Połączono z bazą danych<br />"; $this->connected = true;
}
public function query( $query )
{
echo "Wykonujesz zapytanie:<pre>$query</pre><br />"; }
}
class QueryMaker extends DB
{
public function makeSelect( $table, $cols = '*' )
{
if( $this->connected )
{
echo "OK, jesteś połączony<br />";
$query = "SELECT $cols FROM {$this->prefix}{$table}";
$this->query( $query );
}
}
}
$query = new QueryMaker();
$query->makeSelect( 'tabela' );
$query->makeSelect( 'tabela2', 'a, b, c' );
?>
Różnica jest taka, że tworzymy tylko obiekt klasy QueryMaker. Jako że klasa ta nie ma swojego konstruktora to wywoływany jest konstruktor rodzica i nawiązywane jest połączenie z bazą danych. Takie rozwiązanie ma jednak sporo wad, np.: nie da się teraz sensownie przekazać parametrów połączenia z bazą - musiałbyś przerobić klasę DB na statyczną. Trzeba także zrobić z QueryMakera
Singleton bo każda nowa instancja będzie nawiązywała nowe połączenie z bazą danych.
Ja proponowałbym coś takiego:
<?php
class DBConfig
{
public static $DBhost = 'localhost'; public static $DBuser = 'root'; public static $DBname = 'test';
public static function setConfig
( array $configValues ) {
self::$DBhost = $configValues['host'];
self::$DBuser = $configValues['user'];
self::$DBpass = $configValues['pass'];
self::$DBname = $configValues['name'];
self::$DBprefix = $configValues['prefix'];
}
}
class DB
{
private $connID = null;
public function __construct()
{
echo "Następuje połączenie z serwerem '" . DBConfig
::$DBuser . ":" . DBConfig
::$DBpass ."@" . DBConfig
::$DBhost . "' i wybranie bazy '" . DBConfig
::$DBname . "'<br />"; }
public function __destruct()
{
echo "Koniec połączenia z serwerem<br />"; }
public function query( Query $query )
{
echo "Wykonuje zapytanie:<pre>$query</pre><br />"; }
}
interface Query
{
public function __toString();
}
class Select implements Query
{
private $queryParts = array();
public function __construct
( $table, array $cols = array() ) {
$this->queryParts['cols'] = empty( $cols ) ?
'*' : implode( ', ', $cols ); $this->queryParts['table'] = $table;
}
public function where( $where )
{
$this->queryParts['where'] = $where;
return $this;
}
public function order( $order, $direction = 'ASC' )
{
$this->queryParts['order'][] = "$order $direction";
return $this;
}
public function limit( $a, $b = null )
{
$this->queryParts['limit'] = is_null( $b ) ?
"$a" : "$a, $b"; return $this;
}
public function __toString()
{
$query = "SELECT {$this->queryParts['cols']}\nFROM " . DBConfig::$DBprefix . "{$this->queryParts['table']}";
if( !empty( $this->queryParts['where'] ) ) { $query .= "\nWHERE ( {$this->queryParts['where']} )";
}
if( !empty( $this->queryParts['order'] ) ) { $query .= "\nORDER BY " . implode( ', ', $this->queryParts['order'] ); }
if( !empty( $this->queryParts['limit'] ) ) { $query .= "\nLIMIT {$this->queryParts['limit']}";
}
return $query;
}
}
class Update implements Query
{
// ...
public function __toString()
{
}
}
class Insert implements Query
{
// ...
public function __toString()
{
}
}
'host' => 'localhost',
'user' => 'root',
'pass' => 'pass',
'name' => 'baza',
'prefix' => 'abc_'
);
DBConfig::setConfig( $DBconfig );
$DB = new DB;
$query = new Select
( 'tabela', array( 'col1', 'col2', 'col3' ) ); $DB->query( $query );
$query = new Select( 'tabela' );
$query->where( 'col1 = 'abcde' AND ( col2 = 321 OR col3 IN ( 0, 2, 4, 6, 8 ) )' )
->order( 'col1' )
->order( 'col3', 'DESC' )
->limit( 50, 25 );
$DB->query( $query );
?>
Warto też poczytać o:
Criteriahttp://www.php.net/manual/pl/language.oop5.static.phphttp://www.php.net/manual/pl/language.oop5...nekudotayim.phphttp://www.php.net/manual/pl/language.oop5.interfaces.phphttp://www.php.net/manual/pl/language.oop5.typehinting.php