- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
<?php
require_once 'MDB2.php';
$dsn = "mysql://user:pass@localhost/db";
$mdb2 = & MDB2::singleton($dsn);
if (PEAR::isError($mdb2)) {
die($mdb2->getMessage());
}
class DB {
static private $instance = NULL;
static private $mdb2 = NULL;
private function __construct() {
self::$mdb2 = & MDB2::singleton();
self::$mdb2->exec("SET NAMES utf8");
self::$mdb2->setFetchMode(MDB2_FETCHMODE_ASSOC);
}
static function getInstance() {
if(self::$instance == NULL) {
self::$instance = & new DB();
}
return self::$instance;
}
public function query($sql = false) {
$res = self::$mdb2->query($sql);
if (PEAR::isError($res)) {
die($res->getMessage());
}
if(!$res->numRows()) {
return FALSE;
}
return $res;
}
private function __clone() {
}
}
class Page{
public $limit = 10;
private $conn = FALSE;
function __construct() {
$this->conn = & DB::getInstance();
}
public function getPageList() {
$result = FALSE;
$sql = "SELECT * FROM table LIMIT ".$this->limit;
$res = $this->conn->query($sql);
if($res) {
$result = $res->fetchAll();
}
return $result;
}
}
$p = & new Page();
$nodes = $p->getPageList(25);
print '<pre>'.print_r($nodes, 1).'</pre>';
?>
Дайте, пожалуйста, оценку такой конструкции. Не говнокод ли?
- не есть хорошо....
лучше бы было, если имя таблицы передавалось бы в параметрах метода:
$sql = "SELECT * FROM ' " . $table . " ' LIMIT "
$sql = "SELECT * FROM [ " . $table . " ] LIMIT "
-- не помню как будет точнее, если вдруг имя таблицы будет кириллицей;
function getPageList();
$p->getPageList(25);
-- функция ведь объявлена без параметров, зачем в неё передавать параметр?
а так вроде норм (мб чот упустил)
Вы хуйню написали...
Дело не в возможности инъекции или нет, это не продакшн код. Собственно говоря, суть вопроса. Класс DB враппер MDB2, что позволяет не таскать по всему коду проверку на PEAR::isError() а делать его в одном месте, (класс легко расширить любыми другими методами). Конкретно смущает реализация синглтона DB::getInstance(). Чем смущает сказать не могу, может кто-то знает, как это по другому делается?
P.S.
function getPageList();
$p->getPageList(25);
-- функция ведь объявлена без параметров, зачем в неё передавать параметр?
да... проебал должно быть примерно так:
function getPageList($limit = 0) {
if(!empty($limit) && is_numeric($limit)) { $this->limit = $limit; }
.....
>>не таскать по всему коду проверку на PEAR::isError() а делать его в одном мест
и делать die, что бы клиентский код не смог ни залогировать ошибку ни передать управление дальше.
Особенно это клево, если Вы будете писать phpmyadmin например. Надо кидать exception или делать логирование прямо там.
>>Конкретно смущает реализация синглтона DB::getInstance().
Одиночек так и делают.
на худой конец так:
Итого: единственный смысл Вашей обертки это "SET NAMES utf8". Имеет право на существование впринципе, особенно если заменить die на логирование и exception.
Класс Page мы не обсуждаем, верно?
Есть с пятой версии.
Меня смущает тем, что в метод MDB2::singleton() нужно передавать параметр инициализации. Реализуя "одиночку", я предпочитаю писать конструктор так, чтобы он сам доставал откуда ему надо конфигурационные данные. Это делает возможным ленивую инициализацию, когда класс инициализируется не раньше, чем он потребуется другим частям программы.
Ну ещё я всё-таки предпочитаю называть метод singleton(), а не getInstance(), следуя совету coding standard'а ZF (чтобы из названия метода следовало его назначение). Но это уже личное предпочтение.