Как эффективно подключиться к mysql в php без повторного подключения при каждом запросе - PullRequest
13 голосов
/ 25 января 2010

Мне надоело переписывать мой код каждый раз, когда я узнаю что-то новое о php (например, тот факт, что соединения mysql не могут передаваться в сеансе как дескриптор).

Как реализовать подключение mysql в своих проектах? Многие люди предложили «пул соединений», но после прочтения руководства я все еще потерялся. Это как: "пул соединений - mysql_pconnect!" - я: "и ... как это отличается от реальности? Можете ли вы передать mysql_pconnect во время сеанса? Почему эта, казалось бы, таинственная аура ??"

Позвольте мне объяснить мою ситуацию. У меня есть функция под названием «query1»:

function query1($query)
{
    $db = new mysql(HOST,USER,PASS,DBNAME);
    $result = $db->query($query);
    $db->close();
    return $result;
} 

Это похоже на разборчивый и неэффективный способ запроса базы данных ( особенно , так как вам нужен дескриптор mysql для таких функций, как mysql_real_escape_string). Какая правильная форма для этого? Может ли кто-нибудь помочь мне?

Спасибо, я очень ценю хороший честный ответ.

Ответы [ 2 ]

15 голосов
/ 25 января 2010

Обычно соединения происходят после загрузки страницы. AKA

class Database{
    public function connect()
    {
         $this->connection = mysql_connect();
    }

    // This will be called at the end of the script.
    public function __destruct()
    {
        mysql_close($this->connection);
    }

    public function function query($query)
    {
        return mysql_query($query, $this->connection);
    }
}
$database = new Database;
$database->connect();

$database->query("INSERT INTO TABLE (`Name`) VALUES('Chacha')");

По сути, вы открываете соединение в начале страницы, закрываете его на конечной странице. Затем вы можете делать различные запросы на странице и ничего не делать с подключением.

Вы можете даже сделать mysql_connect в конструкторе, как подсказывает Эрик.


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

Global $db;

$db = new Database;
// ... do startup stuff

function doSomething()
{
    Global $db;
    $db->query("Do Something");
}

О, и никто не упомянул, что вам не нужно передавать параметр. Просто подключите

mysql_connect();

Тогда mysql_query будет использовать только последнее соединение, независимо от области действия.

mysql_connect();

function doSomething()
{
    mysql_query("Do something");
}

По комментариям:

Я думаю, вы должны использовать mysql_pconnect () вместо mysql_connect (), потому что mysql_connect () не использует пул соединений. - ночной кодер

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

1 голос
/ 25 января 2010

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

Вот пример, который вы просили:

// this code should be executed on every page/script load:
$adoConn = ADONewConnection(...);
$adoConn->PConnect(...);

// ...

//And then in any place you can just write:
global $adoConn;
$adoConn->ExecuteNonQuery("INSERT INTO test SET Value = 'Hello, world!'");

Что касается вашего вопроса "как реализовать пул соединений". Вы не Он поддерживается сервером за сценой и используется, если вы (или библиотека PHP для работы с PHP) используете функцию mysql_pconnect ().

PS. Если вы боитесь хранить $ adoConn как глобальную переменную (а я нет), вы можете создать класс со статическим свойством:

class DB
{
  public static $adoConn;
}

// ...

DB::$adoConn->ExecuteNonQuery(...);
...