Подтвердить что ты не робот

Объект доступа к данным PHP

Я пытаюсь выяснить, правильно ли я использую шаблон DAO и, точнее, насколько абстрактное db-упорство должно быть к тому моменту, когда оно попадает в мои классы-сопоставления. Я использую PDO как объект абстракции доступа к данным, но иногда мне интересно, пытаюсь ли я слишком сильно абстрагировать запросы.

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

class DaoPDO {

    function __construct() {

        // connection settings
        $this->db_host   = '';
        $this->db_user   = ''; 
        $this->db_pass   = ''; 
        $this->db_name   = '';


    }

    function __destruct() {

        // close connections when the object is destroyed
        $this->dbh = null;

    } 


    function db_connect() {

        try { 

            /**
             * connects to the database -
             * the last line makes a persistent connection, which
             * caches the connection instead of closing it 
             */
            $dbh = new PDO("mysql:host=$this->db_host;dbname=$this->db_name", 
                            $this->db_user, $this->db_pass, 
                            array(PDO::ATTR_PERSISTENT => true));


            return $dbh;

        } catch (PDOException $e) {

            // eventually write this to a file
            print "Error!: " . $e->getMessage() . "<br/>";
            die();

        }


    } // end db_connect()'



    function select($table, array $columns, array $where = array(1=>1), $select_multiple = false) {

        // connect to db
        $dbh = $this->db_connect();

        $where_columns  = array();
        $where_values   = array();

        foreach($where as $col => $val) {

            $col = "$col = ?";

            array_push($where_columns, $col);
            array_push($where_values, $val);

        }


        // comma separated list
        $columns = implode(",", $columns);

        // does not currently support 'OR' arguments
        $where_columns = implode(' AND ', $where_columns);



        $stmt = $dbh->prepare("SELECT $columns
                               FROM   $table
                               WHERE  $where_columns");


        $stmt->execute($where_values);

        if (!$select_multiple) {

            $result = $stmt->fetch(PDO::FETCH_OBJ);
            return $result;

        } else {

            $results = array();

            while ($row = $stmt->fetch(PDO::FETCH_OBJ)) {

                array_push($results, $row);

            }

            return $results;

        }



    } // end select()


} // end class

Итак, мои два вопроса:

  • Является ли это правильным использованием DAO, или я неправильно истолковываю его?

  • Является ли абстрагирование процесса запроса до такой степени ненужным или даже необычным? Иногда я чувствую, что я пытаюсь сделать вещи слишком легкими...

4b9b3361

Ответ 1

Похоже, что вы строите слой абстракции persistence поверх PDO (который сам по себе является персистентным слоем), а не объектом доступа к данным. Хотя существует множество форм, которые может принимать DAO, цель состоит в том, чтобы отделить вашу бизнес-логику от механизма сохранения.

  Business Logic
        |
        v
Data Access Object
        |
        v
 Persistence Layer

DAO с db_connect и select слишком сильно моделируется после слоя сохранения. Простейшая форма общего DAO состоит в том, чтобы обеспечить основные операции CRUD на уровне объекта, не подвергая внутренности механизма персистентности.

interface UserDao
{
    /**
     * Store the new user and assign a unique auto-generated ID.
     */
    function create($user);

    /**
     * Return the user with the given auto-generated ID.
     */
    function findById($id);

    /**
     * Return the user with the given login ID.
     */
    function findByLogin($login);

    /**
     * Update the user fields.
     */
    function update($user);

    /**
     * Delete the user from the database.
     */
    function delete($user);
}

Если ваши бизнес-объекты являются базовыми объектами модели PDO, вы можете вернуть их из DAO. Имейте в виду, что в зависимости от выбранного вами механизма сохранения, это может быть не идеальным. Я не работал с PDO, но предполагаю, что он похож на другие инструменты ORM, которые создают стандартные объекты PHP, не привязывая бизнес-логику к API PDO. Так что вы, наверное, здесь хорошо.

Если вы выполняли персистентность, обратившись непосредственно к библиотеке mysqli, например, вы захотите скопировать данные в/из наборов результатов в свои собственные объекты модели. Это задача DAO, чтобы не допустить ее из бизнес-логики.

Используя интерфейс для DAO, вы можете реализовать его для разных инфраструктур персистентности: PDO, Doctrine, raw SQL, что угодно. Хотя вы вряд ли переключите методы mid-project, стоимость использования интерфейса незначительна по сравнению с другими его преимуществами, например. используя макет в модульном тестировании.

Ответ 2

  • Это необязательно, но это, безусловно, обычная практика. Есть много библиотек, которые абстрагируют waaaaay дальше, чем то, что вы делаете:)