Несколько таблиц для одной модели с использованием Zend_Model_Mappers и Zend_Db_Table_Abstract

#php #model-view-controller #zend-framework #zend-db

#php #model-view-controller #zend-framework #zend-db

Вопрос:

не уверен, что в последнее время я задаю слишком много вопросов о stackoverflow, но я чувствую, что документация Zend Framework ужасна. Кажется, что примеры очень расплывчаты и не похожи на то, что используется в реальном мире. Они поощряют использование фреймворка для аккуратного и организованного кода, а затем не упоминают, как ему следует следовать: D

Так или иначе! В старом приложении, которое я в настоящее время переношу на Zend, у меня была бы функция с именем register, например:

 function register($username, $password, $email, $etc) {
    // Do stuff
    // Insert $email and other stuff into `user_profile` table
    // Insert $username and $password into the `user` table
}
  

Но теперь с Zend… Я следил за их руководством по гостевой книге, чтобы начать работу, и у меня есть следующие модели: User , UserMapper .
И у меня есть DbTables для каждой отдельной таблицы в моей базе данных, например: User , UserProfile .

Итак, мне нравится функциональность, когда вы регистрируетесь, создаете пользовательский объект, а затем вызываете save mapper, который записывает объект в базу данных, но дело в том, что некоторые из этих пользовательских фрагментов попадают в таблицу профилей пользователей. Примером приложения гостевой книги является то, что в UserMapper вы вводите только одну таблицу (User) и записываете в нее… ну, я имею в виду, я мог бы просто сделать что-то вроде:

 // Insert or Update data to user table
$this->getDbTable()->insert($user_data);
// Insert or Update User Profile data
$this->setDbTable('UserProfile');
$this->getDbTable()->insert($user_profile);
  

Но это просто кажется немного … хакерским. Каков фактический рекомендуемый способ работы с несколькими таблицами?

Кроме того, если у меня есть пользовательские запросы… я должен поместить их в созданный DbTable класс или в UserMapper класс? Я не совсем понимаю, для чего на самом деле нужно расширение DbTable. Все, что говорится в руководстве, — это сделать это, и это на самом деле не объясняет преимущества / причины / использования относительно того, почему вы это делаете.

Спасибо, Dom

Комментарии:

1. «Предпочтение «композиции объектов» перед»наследованием классов»». (Банда четырех 1995:20)

2. Итак, я предполагаю, что вы имеете в виду, что вместо того, чтобы использовать User->save () только для захвата и обработки одного DbTable ‘User’, он должен использовать несколько таблиц в одной функции? Итак, я делаю то, что я говорил, чувствовал себя немного взломанным. Установите dbtable(‘user’) и обновите его, а затем установите dbtable(‘userprofile’) и делайте что угодно

3. Что вы делаете со своими пользовательскими запросами?

Ответ №1:

Во-первых, вы не можете задавать слишком много вопросов по SO. Для этого и существует сайт, нет вопросов = нет ответов = нет ТАК. 🙂

Ваш класс usermapper может иметь $user $userProfile свойства и register() метод. Затем метод register обращается к нужным методам из этих таблиц. Приведенный ниже пример кода является базовым и не будет работать как есть, но он дает вам общую идею.

Вместо наследования свойств и методов одного класса используется композиция для предоставления доступа к нескольким классам. Другими словами, этот класс «имеет» Zend_Db_Tables, а не «является» Zend_Db_Table. Надеюсь, разница очевидна, и вы можете увидеть некоторые преимущества в работе таким образом.

В вашем контроллере:-

 public function indexAction() {
    $userMapper = new Application_Model_Usermapper();
    $userMapper->register($username, $password, $email, $etc);
}
  

В вашей модели (извините, я еще не удосужился использовать интервал между именами):-

 class Application_Model_Usermapper
{
    private $user;
    private $userProfile;

    public function __construct()
    {
        $config = array(
            'name'      => 'userTable',
            'primary'   => 'userid'
        );
        $this->user = new Zend_Db_Table($config);

        $config = array(
            'name'      => 'userProfileTable',
            'primary'   => 'userid'
        );
        $this->userProfile = new Zend_Db_Table($config);
    }

    public function register($username, $password, $email, $etc)
    {
        $this->user->insert($userdata);
        $this->userProfile->insert($userProfileData);
    }  
}
  

Комментарии:

1. Круто, спасибо за это. Вместо этого я создал новый экземпляр sof Application_Model_DBTable. Распространяется ли это на мои транзакционные запросы и т. Д.? Я потратил много времени в своем старом приложении, убедившись, что все работает именно так, и чувствую, что возвращаюсь назад, если это не так :/

2. Взгляните на это

Ответ №2:

Ваш класс Mapper должен взаимодействовать с несколькими таблицами, поэтому вам нужно несколько методов set / getDbTable, например:

 public function setUserDbTable($dbTable) {}    
public function getUserDbTable() {}

public function setUserProfileDbTable($dbTable) {}    
public function getUserProfileDbTable() {}
  

Затем в других ваших методах вы можете использовать соответствующую таблицу, например:

 $this->getUserDbTable()->insert($userData);
$this->getUserProfileDbTable()->insert($userProfileData);
  

И аналогично для других взаимодействий в других методах.