Как получить mysqli_connect () для возврата RESOURCE, чтобы он мог быть использован с define ()

Я заметил кое-что во время тестирования различных методов подключения MySQL в PHP.

Обычно я использую odbc_connect () при подключении к базе данных в PHP. Я сохраняю переменную resouce, которую odbc_connect () возвращает в глобальную константу (используя функцию define ()), к которой я могу легко получить доступ во всем приложении. Вот так:

Использование odbc_connect () и сохранение возвращаемого значения в константу работает нормально:

<?php
define("_conn", odbc_connect("Driver={MySQL ODBC 5.3 Unicode Driver};Database=MyDB;", "user", "pass"));
?>

Сохранение возвращаемого значения mysql_connect () (устаревшего) в константу также работает нормально:

<?php
define("_conn", mysql_connect("localhost", "user", "pass", "MyDB"));
?>

Однако попытка сохранить возвращаемое значение mysqli_connect () в константу НЕ Работа:

<?php
define("_conn", mysqli_connect("localhost", "user", "pass", "MyDB"));
?>
Warning: Constants may only evaluate to scalar values in C:\...\script.php on line 164

Это неудачно, так как было бы неплохо использовать mysqli_connect () для установления соединения и сохранения дескриптора в константу, где odbc_connect () недоступен. Я провел исследование и обнаружил, что единственными двумя функциями подключения к базе данных, которые я могу использовать с MySQL, которые возвращают RESOUCE (и могут использоваться с функцией define ()), являются odbc_connect () и mysql_connect () (устаревшая). Смотрите эту ссылку: http://php.net/manual/en/resource.php

Есть ли способ заставить mysqli_connect () возвращать RESOUCE, чтобы я мог использовать его возвращаемое значение в константе (используя функцию define ())?

PDO также не возвращает RESOUCE.

0

Решение

я бы рекомендовал использовать шаблон Singleton для этого случая
Вот пример:

<?php
class PDOConnection {

/**
* singleton instance
*
* @var PDOConnection
*/
protected static $_instance = null;

/**
* Returns singleton instance of PDOConnection
*
* @return PDOConnection
*/
public static function instance() {

if ( !isset( self::$_instance ) ) {

self::$_instance = new PDOConnection();

}

return self::$_instance;
}

/**
* Hide constructor, protected so only subclasses and self can use
*/
protected function __construct() {}

function __destruct(){}

/**
* Return a PDO connection using the dsn and credentials provided
*
* @param string $dsn The DSN to the database
* @param string $username Database username
* @param string $password Database password
* @return PDO connection to the database
* @throws PDOException
* @throws Exception
*/
public static function getConnection() {$dsn = 'mysql:dbname=_____;host=_____';
$username = '_____';
$password = '_____';

$conn = null;
try {

$conn = new \PDO($dsn, $username, $password);

//Set common attributes
$conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);

return $conn;

} catch (PDOException $e) {

//TODO: flag to disable errors?}
catch(Exception $e) {

//TODO: flag to disable errors?}
}

/** PHP seems to need these stubbed to ensure true singleton **/
public function __clone()
{
return false;
}
public function __wakeup()
{
return false;
}
}

?>

Тогда вы можете использовать его из любого места:

$dbh =  PDOConnection::getConnection();
2

Другие решения

Ну, как видите, PHP не позволяет хранить нескалярные значения в константах.

Но вы все еще можете понять, одиночка шаблон или реестр для ваших нужд.

0

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

Шаблон синглтона позволяет легко «глобализировать» соединение между вашим приложением и, конечно, стал знаменитым, потому что в то время было много плохо написанных php-приложений, которые начинали бы каждый скрипт с новых соединений, что приводило к открытию множества дублированных соединений.
Но на самом деле, это даже лучше решить, используя global напрямую на объекте, где это необходимо, чем с помощью singleton. Конечно, для этого было бы лучше внедрить какое-то внедрение зависимостей или шаблон реестра, но я думаю, что это плохой шаблон синглтона в целом, и даже больше, когда речь идет о db в частности.

И вам даже не нужно реализовывать свой собственный обработчик БД или даже использовать какой-либо вендор, как это делается в Doktor OSwaldo пример, Вы получаете все необходимое прямо из PDO:

$db = new PDO('mysql:host=localhost;dbname=myDb', 'user', 'pass');

Вы можете обернуть это в функцию / метод, чтобы манипулировать соединением перед его возвратом или даже реализовать минималистичное хранилище соединений:

function getConnection($which= 'default') {
static $connections = [
// connectionName => connectionOptions
'default' => [
'dsn'  => 'mysql:host=localhost;dbname=myDb',
'user' => 'user',
'pass' => 'pass',
// 'option' => value,
// ...
],
// ...
], $dbStore = [];

if (isset($dbStore[$which])) {
return $dbStore[$which];
}

if (!isset($connections[$which])) {
throw new \Exception("DB setup not supported");
}

$dbStore[$which] = new \PDO($connections[$which]['dsn'], $connections[$which]['user'], $connections[$which]['pass']);

// eventually set some options that could be stored in $connections[$which]
// $dbStore[$which]->setAttribute( ...

return $dbStore[$which];
}

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

// get default connection
$defaultDb = getConnection();

// get another connection
$anotherDb = getConnection('another');

Конечно, вам лучше хранить параметры соединений в какой-то конфигурации (например, извлекать их при первом вызове getConnection). И этот пример все еще не является идеально тестируемым (только его простота позволяет легко высмеивать), но этого может быть достаточно, как и во многих случаях.

0
По вопросам рекламы [email protected]