Hi, community. Another question. I understand that much has been set forth, but I do not find an answer for myself. Singleton would not like, because of his denial and "anti-usefulness") Suppose there are X models in the controller. Inheritance as it comes from Model. I want to make it easier to do initialization in the parent, so that later I don’t add a bunch of parameters in the descendants.

UPD: Changed so that you can connect to multiple database servers

<?php class Database { private static $_instance; private $current_base; public function __construct() { } /** * @param string $parameter * @return \mysqli */ public function connect($parameter = 'default') { if (empty(self::$_instance[$parameter])) { if (!$this->current_base) { $this->setConnect($parameter); } $database = new \mysqli($this->current_base['server'], $this->current_base['user'], $this->current_base['password'], $this->current_base['database'], $this->current_base['port']); if ($database->connect_error) { die('Ошибка ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ (' . $database->connect_errno . ') ' . $database->connect_error); } $database->set_charset("utf8"); self::$_instance[$parameter] = $database; } return self::$_instance[$parameter]; } public function setConnect($name) { // $database_config['default'] = [...] // Π’ΡƒΡ‚ кстати, ΠΏΡ€ΠΈ ΠΎΠ±ΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΡΡ‚Π²Π°Ρ… Π²Ρ‹Π»Π΅Ρ‚Π°Π΅Ρ‚ нотис, Ρ‚ΠΈΠΏΠ° Π½Π΅ Π²ΠΈΠ΄ΠΈΡ‚ ΠΎΠ½ массив Π² db.php require_once APPPATH . 'config/db.php'; if (is_array($database_config[$name])) { $this->current_base = $database_config[$name]; } else { $this->current_base = $database_config['default']; } } } // Π’ Model public function __construct() { if (!session_id()) { session_start(); } $database = new Database(); $this->db = $database->connect('default'); // Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΊΠ°ΠΊ Π±Ρ‹ ΡΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΈ/ΠΈΠ»ΠΈ Π±Π°Π·Ρƒ Π΄Π°Π½Π½Ρ‹Ρ…(Π² смыслС DATABASE()) // Как Π½ΠΈΠΆΠ΅ Π½Π΅ Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΡ‚, Π² DAtabase $_instance возвращаСтся //$database->setConnect('other'); //$this->db2 = $database->connect('other'); } 

1 answer 1

Maybe so?

 /** * ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Web, Console, etc * * @property DB db */ class Application { } /** * Основной класс для доступа ΠΊ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌ */ class Framework { public static $app; public function __construct($config) { self::$app = new Application(); //Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΈΠ· ΠΊΠΎΠ½Ρ„ΠΈΠ³Π° foreach ($config['components'] as $name => $component) { if (class_exists($component['class'], true)) { self::$app->$name = new $component['class']($component); } else { //throw new Exception("class '{$component['class']}' not found"); } } } } /** * Класс ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ коннСкшСна ΠΊ Π±Π°Π·Π΅ */ class Connection { //ΠŸΡ€ΠΎΠ±Ρ€Π°ΡΡ‹Π²Π°Π΅ΠΌ Π² конструктор настройки коннСкшСна public function __construct($config) { foreach ($config as $property => $value) { $this->$property = $value; } } //Π—Π°Π³Π»ΡƒΡˆΠΊΠ° для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° public function select() { } } //Класс для доступа ΠΊ Π±Π°Π·Π΅ хранящий Π² сСбС ΠΊΠΎΠ½Π½Π΅ΠΊΡˆΠ΅Π½Ρ‹ class DB { /**@var Connection[] $databases */ private $databases = []; //ΠšΠΎΠ½Π½Π΅ΠΊΡˆΠ΅Π½Ρ‹ пробрасываСм Π² конструктор ΠΈΠ· ΠΊΠΎΠ½Ρ„ΠΈΠ³Π° public function __construct($config) { foreach ($config['connections'] as $name => $params) { $this->databases[$name] = new Connection($params); } } //ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ коннСкшСн ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ public function getConnection($connectionName) { return $this->databases[$connectionName]; } } //Базовая модСль class Model { private $dbComponent; public function __construct() { //Π’ΡƒΡ‚ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΡΠ»ΠΎΠΆΠ½ΠΈΡ‚ΡŒ ΠΈ вынСсти Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ. Но ΠΎΠ½ΠΎ Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ? $this->dbComponent = Framework::$app->db; } //ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ коннСкшСн ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ public function setConnect($connectionName) { return $this->dbComponent->getConnection($connectionName); } } //Π Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΠ°Ρ модСль для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° class NewModel extends Model { } //ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ прилоТСния ΠΈΠ· ΠΊΠΎΠ½Ρ„ΠΈΠ³Π° new Framework([ 'components' => [ 'db' => [ 'class' => '\DB', 'connections' => [ 'default' => [ 'class' => '\Mysql', 'hostname' => 'localhost', 'username' => 'root', 'password' => '', ], 'mongo' => [ 'class' => '\Mongo', 'hostname' => 'localhost', 'username' => 'root', 'password' => '', ], ] ] ] ]); //Π‘ΠΎΠ·Π΄Π°Ρ‘ΠΌ модСль, ΠΎΠ±ΡŒΠ΅ΠΊΡ‚ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… автоматичСски создался Π½Π° этапС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ прилоТСния $newModel = new NewModel(); //Ну ΠΈ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ достучатся Π΄ΠΎ Π·Π°Π³Π»ΡƒΡˆΠΊΠΈ Π² коннСкшСнС $newModel->setConnect('default')->select(); 
  • So you can write on Bitrex, and on CO, please at least add comments to the code, and even a couple of words about what it is all about. - Naumov
  • This is suitable for different databases, but now the essence is different. Without singleton, if possible, initialize once - ozornick
  • @ozornick than you singleton then annoy? - Naumov
  • @Naumov - outline structure, for a given question. The code is for informational purposes only, and is not a specific implementation, since here you need to add another bunch of auxiliary logic, and you get a micro application. This is a very extensive topic for the post. As for me, everything is clear. If something needs to be chewed separately, you can always clarify. - Ninazu
  • @ozornick singlton here is only Application. You can move away from it, but this will only complicate the application and will not add scalability at this level. You need to know only the measure. Any pattern has a place to be, and singleton too. The main thing is to use it only where needed. > "Any problem can be solved by introducing an additional level of abstraction, except the problem of too many levels of abstraction" - Ninazu