|
|
|
| только недавно начал изучать ооп
Делаю классы для работы с базами данных.
Есть базовый класс db, который является интерфейсом, и содержит методы connect, error, num_rows и т.п. 2 (пока что) класса db_mysql и db_sqlite реализуют его интерфейс, но методы естественно отличаются (стандартные функции для работы с бд разные). Хочу создать 3 класс db_base_func, который будет содержать базовые простейшие методы выборки и поиска данных, здесь уже функционал один и тот же.
Вопрос собственно в чем: как правильно наследовать классу db_base_func функционал от db_mysql или db_sqlite в зависимости от того, какой из родительских классов используется? То есть как сделать, чтобы db_base_func чтобы он "знал" от какого класса наследовать методы и автоматически их наследовал?
спасибо. если можно, объясните всё на пальцах. и укажите пожалуйста на ошибки если они есть | |
|
|
|
|
|
|
|
для: psychomc
(26.03.2010 в 11:19)
| | В данном случае лучше сделать абстрактный класс вместо интерфейса. Эта задача идеально ложится на паттерн adapter. Fluent interface тут тоже к месту.
Вот как это может выглядеть:
<?
abstract class DB_Abstract {
protected $_query;
protected $_connection;
public function fetchAll() {
$result = array();
while ( $fe = $this->fetch() ) {
$result[] = $fe;
}
return $result;
}
abstract public function connect($params);
abstract public function query($sql);
abstract public function fetch();
abstract public function numRows();
abstract public function escape($str);
}
class DB_Mysql extends DB_Abstract {
public function connect($params) {
$this->_connection = @mysql_connect($params['host'], $params['user'], $params['password']);
if ( $this->_connection ) {
if ( !mysql_select_db($params['db'], $this->_connection) ) {
throw new Exception('База данных '.$params['db'].' не пашет');
}
} else {
throw new Exception('Не могу приконнектиться к СУБД');
}
}
public function query($sql) {
if ( $this->_connection ) {
$this->_query = mysql_query($sql, $this->_connection);
if ( !$this->_query ) {
throw new Exception(mysql_error($this->_connection));
} else {
return $this;
}
} else {
throw new Exception('Соединения с СУБД нет. Запрос не был осуществлён.');
}
}
public function fetch() {
if ( $this->_query ) {
return mysql_fetch_assoc($this->_query);
} else {
throw new Exception('Нечего фетчить');
}
}
public function numRows() {
// ...
}
public function escape($param) {
if ( $this->_connection ) {
return mysql_real_escape_string($param, $this->_connection);
} else {
return mysql_escape_string($param);
}
}
}
$o = new DB_Mysql;
$o->connect(array('host' => 'l', 'user' => 'root', 'password' => '', 'db' => 'test'));
print_r($o->query("SHOW TABLES")->fetchAll());
|
| |
|
|
|
|
|
|
|
для: Саня
(26.03.2010 в 12:53)
| | Саня, спасибо за ответ, но честно сказать не уловил...
ну допустим создал я еще один класс:
<?php
class DB_Mysqi extends DB_Abstract { }
?>
|
и замутил соответственно для него все методы абстрактного. далее я хочу создать класс db_base_func, который должен наследовать уже методы того базового, который я в данный момент использую (DB_Mysql или DB_Mysqi). как мне создать класс db_base_func так (или в других классах это сделать), чтобы он сам выбрал быть ему наследником DB_Mysql или DB_Mysqi ?
p.s если что - извиняюсь за тупость | |
|
|
|
|
|
|
|
для: psychomc
(26.03.2010 в 13:08)
| | В DB_Abstract уже реализованы методы, которые вы хотите выделить в db_base_func (в моём примере это fetchAll()). | |
|
|
|
|
|
|
|
для: Саня
(26.03.2010 в 13:14)
| | Саня, дорубил,
но все-таки сделал по-другому
<?php
abstract class db_base_func
{
function test()
{
$this->pr();
}
}
class db_sqlite extends db_base_func implements db
{
......
public function pr()
{
echo "test";
}
}
// вызов
$db = new db_sqlite("sqlite");
// подключаемся к sclite
$db->connect();
$db->test();
?>
|
что скажете? | |
|
|
|
|
|
|
|
для: psychomc
(26.03.2010 в 13:59)
| | Зачем вы разделили интерфейс и базовый класс? Этому есть какое-то обоснование? | |
|
|
|
|
|
|
|
для: Саня
(26.03.2010 в 14:17)
| | базовым его сложно назвать.
дело в том, что интерфейс db должны обязательно реализовывать db_mysql и db_sqlite, а db_base_func у меня будет содержать стандартные простейшие операции для работы базой (max. min, count) и т.п. получается что вызывать его методы я буду из объекта производного класса, отдельно их использовать смысла нет. вроде бы очень похоже на ваш вариант, но с использованием интерфейса, и немного сложнее.
есть какие-нибудь ошибки с точки зрения ООП? | |
|
|
|
|
|
|
|
для: psychomc
(26.03.2010 в 15:03)
| | Если бы были ошибки, PHP сам сказал бы об этом. | |
|
|
|
|
|
|
|
для: Саня
(26.03.2010 в 15:13)
| | я понимаю. я имел ввиду другое. как по-вашему, оправдано ли было с моей стороны делать еще один абстрактный класс? | |
|
|
|
|
|
|
|
для: psychomc
(26.03.2010 в 15:25)
| | Если db_base_func и db не будут использоваться где-то ещё отдельно друг от друга, то такое разделение не имеет смысла. | |
|
|
|
|
|
|
|
для: Саня
(26.03.2010 в 15:30)
| | понял вашу мысль.
скорее всего не будут.
спасибо за ответы и за интерес, проявленный к теме. вопрос исчерпан | |
|
|
|