class connector { private static $db; function __construct() { $this->db = null; $this->connect(); } private function connect() { $this->db = new PDO('mysql:host=localhost;dbname=database;charset=utf8','user','pass'); } public static function getDB() { if (!isset(self::$db)) { self::$db = new connector(); } return self::$db; }
РЕДАКТИРОВАНИЕ
// this was my original function, I had reduced it for less space. my deepest regrets, I won't do it again. public function getValue($sql,$val='') { if ($val != '') { $data = $this->db->prepare($sql); $data->execute($val); return $data->fetch(PDO::FETCH_COLUMN); } else { return $this->db->query($sql)->fetch(PDO::FETCH_COLUMN); }
используя этот класс, я могу легко использовать объект базы данных pdo из любого места, с пользовательскими функциями.
$db = connector::getDB(); // var_dump() db:object(connector)#1 (1) { ["db":"connector":private]=> object(PDO)#2 (0) { } } $db->getValue('SELECT foo FROM bar'); //succeeds $db->query('SELECT foo FROM bar')); // throws // Fatal error: Call to undefined method connector::query()
если я верну фактический объект param вместо всего объекта:
return self::$db->db; db:object(PDO)#2 (0) { }
роли обмена запросами
$db->getValue('SELECT foo FROM bar'); // throws // Fatal error: Call to undefined method connector::getValue() $db->query('SELECT foo FROM bar')); //succeeds
Как я могу использовать оба объекта с одним и тем же объектом , эффективно используя $db->query()
и $db->getValue()
в том же скрипте.
Прежде всего, ваш getValue()
не имеет одной важной функции – поддержки подготовленных операторов . Без возможности запуска динамических запросов это значение близко к нулю.
Во-вторых, если вы используете синглтон в любом случае – тогда нет необходимости в дополнительном методе для получения экземпляра. В настоящее время singleton может делать это сам по себе.
Как насчет этого? Я написал это, чтобы сделать использование PDO менее многословным, используя аккуратную цепочку методов. Статический класс DB
уже является экземпляром PDO, без необходимости его экземпляра с дополнительным вызовом. В результате вы можете запускать любую команду PDO где угодно:
DB::query('SELECT foo FROM bar LIMIT 1')->fetchColumn();
Это занимает немного больше места, чем ваше, но по крайней мере оно дает вам доступ к полному синтаксису PDO, включая поддержку подготовленных операторов
DB::prepare('SELECT foo FROM bar WHERE id=?')->execite([$id])->fetchColumn();
а также все другие методы выборки
DB::query('SELECT foo FROM bar')->fetchAll(PDO::FETCH_COLUMN);
Повторное использование переменной $db
как для статического экземпляра одноэлементного connector
и для частной переменной члена PDO
запутывает. Не уклоняясь от своего подхода к синглтону, попробуйте использовать несколько лучших имен переменных, например
class connector { private static $instance = null; private $db; private function __construct() { $this->db = new PDO('mysql:host=localhost;dbname=database;charset=utf8','user','pass', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ]); } private function __clone() {} // because singletons should not be cloneable public static function getInstance() { if (self::$instance == null) { self::$instance = new self(); } return self::$instance; } /** * @return PDO */ public function getDb() { return $this->db; } public function getValue($sql) { // as is } }
Теперь, если вы должны запустить PDO::query
, вы можете сделать это с помощью метода getDb
…
$db = connector::getInstance(); $db->getValue('SELECT foo FROM bar'); $db->getDb()->query('SELECT foo FROM bar');