How can this be done without crutches and tambourines?

Desirable this type:

try { $db = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); } catch (PDOException $e) { die('PDO->ERROR::'.$e->getMessage()); } 

I decided to try Singleton:

 class DB extends PDO { private $db; public static $Instance = NULL; public static function Instance() { if (self::$Instance == NULL) { self::$Instance = new self(); } return self::$Instance; } public function __construct() { $this->db = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); } public function prepare($sql, $values) { $sth = $this->db->prepare($sql); $sth->execute($values); } } 

But again, the mistakes ...

Fatal error: Call to a member function fetch () on a non-object in.

How to avoid them without making a wrapper?

  • Singleton is fine. >>> But again, errors Fatal error: Call to a member function fetch () on a non-object in. Show the full text of the message and the text around the line indicated by the error. - copist
  • the singleton method __construct is protected so that the "outside" is not done $db = new DB; - copist
  • public function prepare ($ sql, $ values) {$ sth = $ this-> db-> prepare ($ sql); $ sth-> execute ($ values); return $ sth; // I forgot to do this} - copist
  • A singleton is used like this: function doSomeStreetMagic () {$ db = DB :: Instance (); $ sth = $ db-> prepare ('SELECT * FROM user'); while ($ row = $ sth-> fetch ()) {// look strange at the camera}} - copist
  • one
    @Pavel Volyntsev I thank, I already guessed, having re-read the manuals several times. - Eugene Smiths

2 answers 2

Look at the implementation of the components and modules in the Yii framework

for example

 Yii::app()->db->createCommand('SELECT * FROM user'); 

actually reads the config for the db component, and takes the class name from there. Then it instantiates a class instance with the parameters specified in the config file and saves the instance in the component registry under the db code. On a subsequent query, Yii :: app () -> db instances with the db code are taken from the registry. In general, the main idea is that a global register of entities with convenient public access is needed, and then the PDO instance will not need to be passed to the parent, he will find it by the same system-wide name db .

  • I think this is huge and difficult - Eugene Smiths
  • Oh, I’ll tell you straight. Huge. And of course you come up with a compact mastadon, you can say manually. github.com/yiisoft/yii/blob/1.1.14/framework/base/ ... if you remove the comments, it will be 200 lines at most. But komenty something must be read - for that they komenty. I repeat once again: we need a global registry of entities with convenient public access, and then the PDO instance will not need to be passed to the parent, he will find it by the single system-wide name db. - copist
  • Well, of course, I'm lying. In fact, of course difficult. I just got used to it and don't notice the complexity. There's all the magic in the magic method __get () - copist
  • @Pavel Volyntsev I say this is difficult, long and cumbersome. - Eugene Smiths
  • The registry is half measures. If we do, then a full-fledged DI, for a simple implementation, there are not too many lines required either. - etki

if I understand you correctly, then somehow

 class Foo { public function __construct() { $pdo = new PDO(); parent::__construct($pdo); } } 
  • Look, I have a model_me extends model {function me () {here I perform my actions with the database (and I have problems with the fact that for example $ db-> prepare () causes the error Fatal error: Call to a member function prepare () on a non-object in)}} and I do not know what to do - Eugene Smiths
  • I really don't want to make wrappers. - Eugene Smiths
  • @Eugene Smiths may need to use $ this-> db? - zb '
  • @eicto is already used. - Eugene Smiths
  • I do not understand what you mean by "very much I do not want to make wrappers." - copist