Intereting Posts
Проверка, а затем перенаправление на почтовый маршрут в Ларавеле Заполнение результатов запроса пустыми строками Kohana 3.3 Не работает из подкаталога Распределить значение массива в столбце таблицы Каков наилучший способ создания «многоязычного» скрипта в php? PHP, как вызвать ошибку пользователя с trigger_error в деструкторе объекта, когда скрипт отключается? Подключение к удаленной базе данных MS Access с Linux Server с помощью PHP PHP Чтение файла xlsx Excel 2007 Использовать OR внутри, если условие else по обратному порядку порядка в php Laravel быстрее запрашивать все в контроллере или в представлении PHP Предупреждение: сеанс активен. Вы не можете изменить настройки ini-модуля сеанса в это время в /../ Автоматизация Linkedin oAuth usin Curl и PHP Потоковый видеофайл? Загрузить изображение на сервер с iOS не работает Каковы причины различных форм фигурных скобок?

php singleton database connection, является ли этот код плохой практикой?

Я пытаюсь создать простой в использовании одноэлементный класс для подключения к базе данных mysql и делать запросы, код работает отлично, и у меня не было никаких проблем с ним, но поскольку я новичок в ООП, мне интересно, это плохая практика или нет.

Вот класс

class Database { private $databaseName = 'dbname'; private $host = 'localhost'; private $user = 'user'; private $password = 'pass'; private static $instance; //store the single instance of the database private function __construct(){ //This will load only once regardless of how many times the class is called $connection = mysql_connect($this->host, $this->user, $this->password) or die (mysql_error()); $db = mysql_select_db($this->databaseName, $connection) or die(mysql_error()); echo 'DB initiated<br>'; } //this function makes sure there's only 1 instance of the Database class public static function getInstance(){ if(!self::$instance){ self::$instance = new Database(); } return self::$instance; } public function connect() { //db connection } public function query($query) { //queries $sql = mysql_query($query) or die(mysql_error()); return $sql; } public function numrows($query) { //count number of rows $sql = $this->query($query); return mysql_num_rows($sql); } } //Intantiate the class $database = Database::getInstance(); 

и когда я хочу использовать класс, я бы сделал:

 $query = "SELECT * FROM registrations"; echo $database->numrows($query); $sql = $database->query($query); 

Синглтоны – плохая новость.

  • Они вводят глобальное состояние в программу. Большинство программистов должны знать, почему глобальное состояние плохое.
  • Они вводят жесткую связь между синглтоном и любым классом, который его использует. Это означает, что вы не можете повторно использовать классы, о которых идет речь, без повторного использования синглтона.
  • Они производят модульное тестирование классов, которые зависят от проблемы с singleton, потому что вы не можете легко заменить singleton макетом.
  • Они поощряют стиль кодирования, когда классы пытаются решить свои собственные зависимости. Это плохо, потому что это может уменьшить ясность относительно зависимостей, которые имеет класс.
  • PHP имеет архитектуру «Share Nothing», что означает, что синглтоны PHP на самом деле не являются синглтонами вообще, может быть несколько экземпляров в любой момент (по одному на открытый запрос).
  • Что произойдет, если вы вдруг обнаружите в какой-то более поздний срок, что вам действительно нужно больше, чем один из ресурсов, предоставляемых синглтоном? Это более распространенный сценарий, чем вы думаете

Вместо этого вам лучше смотреть на инъекцию зависимостей , поскольку он решает вышеуказанные проблемы.

Я думаю, что singleton может быть в порядке для менеджера соединений, но не для самой связи.

Вы никогда не знаете, когда вам понадобится дополнительное соединение для определенной части вашего развития. Скажем, вам нужно добавить синхронизацию с удаленной базой данных.

Диспетчер соединений (который может управлять несколькими соединениями) может быть одноточечным. Само соединение; нет.

Менеджер соединений должен также иметь возможность загружать «Драйверы», чтобы вы могли инициировать соединение с MySQL и день, когда вам нужны msSQL, sqlite или что-то еще, вы можете добавить необходимые драйверы.

Я бы сказал, это зависит от того, как вы используете класс. Если вы вызываете Database::getInstance() каждый раз, когда хотите использовать базу данных, это плохо с точки зрения ОО, потому что это вредит тестируемости. Если вы сделаете это только один раз, а затем приложите экземпляр к объектам, которые должны работать с базой данных, не так уж плохо использовать singleton (но все же необязательно).

Я предлагаю вам взглянуть на концепцию инъекций зависимостей: http://misko.hevery.com/2008/11/11/clean-code-talks-dependency-injection/ или http://fabien.potencier.org/article/11 / что-это-зависимость инъекции

Этот шаблон будет точным, потому что singleton будет применяться только к текущему сеансу пользователя. Решение действительно сводится к тому, каков ваш приоритет. Если вам нужна более высокая производительность для пользователя, тогда вы хотите разрешить больше подключений к базе данных для каждого пользователя, но если вы хотите ограничить, насколько сильно ваша база данных попадает, то синглтон дает вам хорошую середину дороги.

Единственный положительный аргумент, который я слышал для шаблона проектирования Singleton в PHP, – это разработчик, который реализовал соединение базы данных Singleton совместно с объектом Memcached. На самом деле у меня не было возможности взглянуть на код и производительность, но он смог сформулировать согласованный аргумент.

Лично я не считаю, что шаблон дизайна Singleton очень важен для PHP, который в значительной степени является апатридом в любом случае (как указано выше, когда каждый запрос будет иметь один синглтон).