Лучший способ подключиться к MySQL с php-объектами, используя MySQL-объект - PullRequest
1 голос
/ 29 октября 2009

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

пример:

$dbase = new mysqli('localhost','dbuser','dbpass','dbname');
$oresult = $dbase->query("SELECT `field` FROM `table` WHERE `otherfield` = 12;");
if($oresult->num_rows > 0) {
    $row = $oresult->fetch_row();
    $data = $row[0];
}

но у меня есть другой объект, с которым я хочу поговорить с базой данных.

<?php
class Thing {
    private $sql = '';
    public $results = '';

    public function __construct($sql) {
        $this->sql = $sql;
        $this->get_data();
    }

    private function get_data() {
         // get the stuff from the dbase using $this->sql
         $this->results = 'whatever';
    }
}

$thing = new Thing("SELECT `field` FROM `table` WHERE 1");
// do whatever i want with $thing->results
?>

Где у меня есть строка «// получить материал из базы данных, используя $ this-> sql», я бы хотел подключиться к базе данных и получить данные.

Лучше ли создать новый объект mysqli (с которым я вижу проблемы, потому что мне нужно будет передать информацию о соединении каждому имеющемуся у меня объекту) или я могу как-то ссылаться на уже существующий объект, используя

global $dbase

внутри функции get_data.

Какая лучшая практика?

Ответы [ 3 ]

1 голос
/ 29 октября 2009

Создать класс-оболочку для соединений с БД. Оболочка может быть одноэлементной или хранить соединение mysqli в статическом поле.

class DB {
    static public $_connection;
    static function connection(...) {
        if (! self::$_connection) {
            self::$_connection = mysqli_connect(...);
        }
        return self::$_connection;
    }
}

Это также позволяет легко изолировать учетные данные пользователя, сохраняя их в одном скрипте или файле конфигурации.

Вместо того, чтобы выставлять соединение через класс DB, вы можете использовать сам класс DB. Превратите connection() в конструктор, напишите метод prepare() и класс DBStatement.

class DB {
    static private $_connection;
    function __construct(...) {
        if (! self::$_connection) {
            self::$_connection = mysqli_connect(...);
        }
    }
    // returns an SQLStatement
    function prepare($query) {
    }
}
0 голосов
/ 30 октября 2009

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

class dbtool 
{
    private static $instance   = false;
    private static $connections= false;

    private function __construct() { 
        if( ! self::$instance ) {
            self::$instance = $this;
            self::$connections = array();
        }
    }
    public function getInstance() { 
        if( ! self::$instance ) 
            self::$instance = new dbtool();
        return self::$instance;
    }
    public static function getConnection( $hint )
    {
        if( ! self::$instance ) return false;
        if( ! array_key_exists( $hint, self::$connections ))
            self::$connections[ $hint ] = self::$connectByHint( $hint );
        return self::$connections[ $hint ];
    }
    // a list of database creds by hint, etc...
    private static function connectByHint( $hint ) {}
}

Закрытие соединения происходит при выходе из скрипта. Если вы запускаете пакетный процесс, например, демон, вы можете захотеть обернуть сами соединения в собственный класс соединителя, который выполняет mysqli_ping (), чтобы подтвердить, что соединение еще живо, а если нет, переподключиться.

Я также не рекомендую хранить пароли базы данных в качестве переменных-членов, так как они могут быть предоставлены с помощью print_r () или var_export (). Можете ли вы угадать, что я бы предложил для паролей?

0 голосов
/ 29 октября 2009

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

Итак, если мне нужно сделать 3 запроса к базе данных, чтобы получить результаты, которые мне нужно вернуть, я сделаю это, но в конце я закрою это соединение.

Итак, мой контроллер устанавливает соединение, выполняет необходимые вызовы DAO и затем закрывает его.

Итак, если этот класс Thing просто использует соединение, которое, возможно, уже было установлено, тогда я просто установлю соединение и затем закрою его в этом классе.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...