Шаблон класса MySQLi для соединения, закрыть, оставить открытым? - PullRequest
1 голос
/ 29 ноября 2011

Я хотел бы знать, будет ли создание такого класса, как приведенный ниже, хорошей практикой.

Поэтому я бы использовал объект self :: $ mysqli каждый раз, когда мне нужно выполнить какую-то работу и установить соединениебудет закрыт только на __desctruct ().Кроме того, расширение класса все равно будет поддерживать только одно соединение, так как $ mysqli объявлен как статический.

таким образом, у меня будет только одно соединение при мысли сценария

class db {
 protected static $mysqli;

 function __contruct(){
  $this->mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_DATABASE);
  // DB_HOST, DB_USER, DB_PASS, DB_DATABASE defined elsewhere
 }

 function __destruct(){
  $this->mysqli->close();
 }
}

Я хотел бы знать вашепонимание этого.

Ответы [ 2 ]

3 голосов
/ 29 ноября 2011

Я хотел бы знать, будет ли хорошей практикой создание такого класса, как приведенный ниже.

Я бы посчитал это не очень хорошей практикой.Это особенно по одной причине: проблема, которую вы описываете, почему вы считаете, что она вам нужна: только одно соединение на запрос.

Вам не нужно ничего кодировать.mysqli имеет хорошую встроенную функцию, соединение по умолчанию.Он выбирает параметры соединения с базой данных из настроек (конфигурации) ini каждый раз, когда вы создаете новый экземпляр:

$db = new mysqli;

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

Другая плохая практика заключается в том, что вы вводите Singleton Doc здесь, что-то вроде:

class MysqliSingleton extends mysqli
{
    private static $instance;
    /**
     * @return MysqliSingleton
     */
    public function getInstance()
    {
        if (NULL === self::$instance)
            self::$instance = new self();
        return self::$instance;
    }
    private function __construct()
    {
    }
    public function __clone()
    {
         throw new RuntimeException('Clone is not allowed.');
    }
    public function __wakeup()
    {
        throw new RuntimeException('Unserializing is not allowed.');
    }
}

Это будет работать так:

$mysqli = MysqliSingleton::getInstance();

и всегда будет возвращать тот экземпляр mysqli, который может быть тем, что вы ищете.Однако синглеты считаются вредными, поскольку они могут создавать множество проблем, см. Связанный с этим вопрос Кому нужны синглтоны? .

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

interface ContextMysqli
{
    /**
     * @return mysqli
     */
    public function getMysqli();
}

class Context implements ContextMysqli
{
    private $mysqli;
    public function getMysqli()
    {
        $this->mysqli || $this->mysqli = new mysqli();
        return $this->mysqli;
    }
}

Когда ваши сценарии запускаются, просто создайте экземпляр своего контекста и передайтеэто для каждой части вашего кода, где вам это нужно:

$context = new Context();
...
$result = do_some_db_work($context);
...
function do_some_db_work(ContextMysqli $context)
{
    $mysqli = $context->getMysqli();
    ...
}

Это предложение может быть немного недальновидным, но оно лучше, чем одноэлементное, хотя и не вводит много шума.Преимущество заключается в том, что вы инкапсулировали логику, когда для создания объекта mysqli не требуется одиночный код.Ваш код теперь не зависит от глобального или статического контекста.

3 голосов
/ 29 ноября 2011

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

То, что вы настроили выше, будет только когда-либо оставаться открытым при соединении, вы можете посмотреть на шаблон синглтона, но это серьезно излишне для этого базового варианта использования.

Как говорится, нет смысла закрывать его в конце:)

...