Введение в Zend Framework

 Learning Zend Framework

appendix

 Zend Framework Reference


  • Zend_Gdata
  • Zend_Http
  • Zend_InfoCard
  • Zend_Json
  • Zend_Layout
  • Zend_Ldap
  • Zend_Loader
  • Zend_Locale
  • Zend_Log
  • Zend_Mail
  • Zend_Markup
  • Zend_Measure
  • Zend_Memory
  • Zend_Mime
  • Zend_Navigation
  • Zend_Oauth
  • Zend_OpenId
  • Zend_Paginator
  • Zend_Pdf
  • Zend_ProgressBar
  • Zend_Queue
  • Zend_Reflection
  • Zend_Registry
  • Zend_Rest

  • Zend_Search_Lucene
  • Zend_Serializer
  • Zend_Server
  • Zend_Service
  • Zend_Session
  • Zend_Soap
  • Zend_Tag
  • Zend_Test
  • Zend_Text
  • Zend_TimeSync
  • Zend_Tool
  • Zend_Tool_Framework
  • Zend_Tool_Project
  • Zend_Translate
  • Zend_Uri
  • Zend_Validate
  • Zend_Version
  • Zend_View
  • Zend_Wildfire
  • Zend_XmlRpc
  • ZendX_Console_Process_Unix
  • ZendX_JQuery
  • Ttranslation 27.4% Update 2010-11-28 - Revision 23238 - Version ZF 1.11.x

    27.6. Zend_Db_Table_Row

    27.6.1. Введение

    Zend_Db_Table_Row является классом, содержащим отдельную строку объекта Zend_Db_Table. Когда вы производите запрос через класс таблицы, результат возвращается в виде набора объектов Zend_Db_Table_Row. Вы можете также использовать этот объект для создания новых строк и их добавления в таблицу БД.

    Zend_Db_Table_Row является реализацией паттерна Row Data Gateway.

    27.6.2. Извлечение строки

    Zend_Db_Table_Abstract предоставляет методы find() и fetchAll(), которые возвращают объект типа Zend_Db_Table_Rowset, и метод fetchRow(), возвращающий объект типа Zend_Db_Table_Row.

    Пример 27.110. Пример извлечения строки

    $bugs = new Bugs();
    $row $bugs->fetchRow($bugs->select()->where('bug_id = ?'1));

    Объект Zend_Db_Table_Rowset содержит коллекцию объектов Zend_Db_Table_Row. Для получения более подробной информации читайте Раздел 27.7, «Zend_Db_Table_Rowset».

    Пример 27.111. Пример получения строки из набора строк

    $bugs = new Bugs();
    $rowset $bugs->fetchAll($bugs->select()->where('bug_status = ?'1));
    $row $rowset->current();

    27.6.2.1. Чтение значений столбцов из строки

    Zend_Db_Table_Row_Abstract предоставляет методы-аксессоры, благодаря которым можно ссылаться на столбцы в строке как на свойства объекта.

    Пример 27.112. Пример чтения столбца из строки

    $bugs = new Bugs();
    $row $bugs->fetchRow($bugs->select()->where('bug_id = ?'1));

    // Вывод значения столбца bug_description
    echo $row->bug_description;

    [Замечание] Замечание

    Более ранние версии Zend_Db_Table_Row сопоставляли аксессоры столбцов и имена столбцов в БД с использованием преобразования строк, называемым инфлекцией.

    Zend_Db_Table_Row в его текущей реализации не использует инфлекцию. Написание аксессоров столбцов должно в точности соответствовать именам столбцов, так, как они представлены в БД.

    27.6.2.2. Получение данных строки в виде массива

    Вы можете получать данные строки, используя метод toArray() объекта строки. Метод возвращает ассоциативный массив имен столбцов и их значений.

    Пример 27.113. Пример использования метода toArray()

    $bugs = new Bugs();
    $row $bugs->fetchRow($bugs->select()->where('bug_id = ?'1));

    // Получение ассоциативного массива столбцов и их значений из объекта Row
    $rowArray $row->toArray();

    // Теперь используется как обычный массив
    foreach ($rowArray as $column => $value) {
        echo 
    "Column: $column\n";
        echo 
    "Value:  $value\n";
    }

    Массив, возвращаемый методом toArray() не может использоваться для обновления данных в БД. Мы можете изменять значения в этом массиве так же, как и в любом другом массиве, но не можете сохранять измененные значения непосредственно из этого массива в БД.

    27.6.2.3. Извлечение данных из связанных таблиц

    Класс Zend_Db_Table_Row_Abstract предоставляет методы для извлечения строк и наборов строк из связанных таблиц. Читайте Раздел 27.8, «Связи между таблицами Zend_Db_Table» для получения более подробной информации о связях между таблицами.

    27.6.3. Редактирование строк в БД

    27.6.3.1. Изменение значений столбцов в строке

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

    Использование аксессоров столбцов для установки значений изменяет значения столбцов в данном объекте строки, но эти изменения еще не фиксируются в БД. Вы можете произвести фиксацию через метод save().

    Пример 27.114. Пример изменения значения столбца в строке

    $bugs = new Bugs();
    $row $bugs->fetchRow($bugs->select()->where('bug_id = ?'1));

    // Изменение значения одного или более столбцов
    $row->bug_status 'FIXED';

    // Обновление строки в БД с новыми значениями
    $row->save();

    27.6.3.2. Вставка новой строки

    Вы можете создавать новые строки для определенной таблицы с помощью метода createRow() класса таблицы. Можно работать с полями этой строки через объектно-ориентированный интерфейс, но строка не сохраняется в БД до тех пор, пока вы не вызовете метод save().

    Пример 27.115. Пример создания новой строки таблицы

    $bugs = new Bugs();
    $newRow $bugs->createRow();

    // Установка значений столбцов
    $newRow->bug_description '...description...';
    $newRow->bug_status 'NEW';

    // Вставка новой строки в БД
    $newRow->save();

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

    Пример 27.116. Пример заполнения новой строки для таблицы

    $data = array(
        
    'bug_description' => '...description...',
        
    'bug_status'      => 'NEW'
    );

    $bugs = new Bugs();
    $newRow $bugs->createRow($data);

    // вставка новой строки в БД
    $newRow->save();

    [Замечание] Замечание

    В более ранних релизах Zend_Db_Table метод createRow() назывался fetchNew(). Мы рекомендуем использовать новое имя метода, несмотря на то, что старое имя метода по-прежнему работает в целях обеспечения обратной совместимости.

    27.6.3.3. Изменение значений в нескольких столбцах

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

    Пример 27.117. Пример использования метода setFromArray() для установки значений в новой строке

    $bugs = new Bugs();
    $newRow $bugs->createRow();

    // Данные помещаются в ассоциативный массив
    $data = array(
        
    'bug_description' => '...description...',
        
    'bug_status'      => 'NEW'
    );

    // Одновременная установка значений всех столбцов
    $newRow->setFromArray($data);

    // Добавление новой строки в БД
    $newRow->save();

    27.6.3.4. Удаление строки

    Вы можете использовать метод delete() объекта строки. Этот метод удаляет из таблицы строки, соответствующие первичному ключу в объекте строки.

    Пример 27.118. Пример удаления строки

    $bugs = new Bugs();
    $row $bugs->fetchRow('bug_id = 1');

    // Удаление строки
    $row->delete();

    Не нужно вызывать метод save() для фиксации удаления, оно сразу выполняется в БД.

    27.6.4. Сериализация и десериализация строк

    Часто бывает удобным сохранять содержимое строки БД для последующего использования. Сериализацией называется действие по преобразованию объекта в форму, удобную для хранения в автономном хранилище (например, в файле). Объекты типа Zend_Db_Table_Row_Abstract доступны для сериализации.

    27.6.4.1. Сериализация объекта строки

    Просто используйте функцию PHP serialize() для получения строки, содержащей представление объекта Row в виде последовательности байт.

    Пример 27.119. Пример сериализации объекта строки

    $bugs = new Bugs();
    $row $bugs->fetchRow('bug_id = 1');

    // Преобразование объекта в сериализованную форму
    $serializedRow serialize($row);

    // Теперь вы можете записать $serializedRow в файл и т.д.

    27.6.4.2. Десериализация данных строки

    Используйте функцию unserialize() для восстановления из строки, содержащей представление объекта в виде последовательности байт. Эта функция возвращает исходный объект.

    Внимание: объект строки возвращается без соединения. Вы можете читать объект Row и его свойства, но не можете изменять значения в строке или выполнять другие методы, требующие соединения с БД (например, запросы к связанным таблицам).

    Пример 27.120. Пример десериализации объекта строки

    $rowClone unserialize($serializedRow);

    // Теперь вы можете использовать свойства объекта, но только для чтения
    echo $rowClone->bug_description;

    [Замечание] Почему объекты строки десериализуются без соединения?

    Сериализованный объект является строкой, которая доступна для чтения всем, кто ею обладает. Это создает угрозу безопасности, которая состоит в том, что в сериализованной строке сохраняются такие параметры, как логин и пароль для соединения с БД, в незашифрованном виде. Для вас может быть нежелательным сохранять такие данные в незащищенном текстовом файле, отправлять его через e-mail или любой другой носитель, который может быть прочитан потенциальным атакующим. Тот, кто прочитает сериализованный объект, не должен иметь возможности использовать его в получении несанкционированного доступа к БД.

    27.6.4.3. Восстановление соединения для объекта строки

    Вы можете восстановить соединение для строки, используя метод setTable(). Аргументом этого метода является объект типа Zend_Db_Table_Abstract, который создается вами. Создание объекта таблицы требует действующего соединения с БД, поэтому при переустановке таблицы объект строки получает доступ к БД. После этого можно изменять значения в объекте строки и сохранять изменения в БД.

    Пример 27.121. Пример восстановления соединения для строки

    $rowClone unserialize($serializedRow);

    $bugs = new Bugs();

    // Привязка строки к таблице с действующим соединением БД
    $rowClone->setTable($bugs);

    // Теперь вы можете производить изменения в строке и сохранять их
    $rowClone->bug_status 'FIXED';
    $rowClone->save();

    27.6.5. Расширение класса строки

    Zend_Db_Table_Row является используемым по умолчанию классом, который наследует от Zend_Db_Table_Row_Abstract. Вы можете определить свой собственный класс для экземпляров строк путем наследования от Zend_Db_Table_Row_Abstract. Для того, чтобы этот класс использовался для хранения результатов запросов к таблице, укажите его имя в защищенном свойстве $_rowClass класса таблицы или в массиве, передаваемом в качестве аргумента конструктору объекта таблицы.

    Пример 27.122. Указание своего класса строки

    class MyRow extends Zend_Db_Table_Row_Abstract
    {
        
    // ...кастомизация
    }

    // Укажите свой класс строки в качестве используемого по умолчанию
    // во всех экземплярах класса таблицы
    class Products extends Zend_Db_Table_Abstract
    {
        protected 
    $_name 'products';
        protected 
    $_rowClass 'MyRow';
    }

    // Или укажите свой класс строки для использования
    // в конкретном экземпляре класса таблицы
    $bugs = new Bugs(array('rowClass' => 'MyRow'));

    27.6.5.1. Инициализация строки

    Если при создании объекта строки требуется выполнять код, реализующий логику приложения, то вы можете поместить этот код в метод init(), который вызывается после того, как были обработаны все метаданные строки. Рекомендуется использовать этот способ вместо переопределения метода __construct, если только не требуется изменять метаданные программным путем.

    Пример 27.123. Пример использования метода init()

    class MyApplicationRow extends Zend_Db_Table_Row_Abstract
    {
        protected 
    $_role;

        public function 
    init()
        {
            
    $this->_role = new MyRoleClass();
        }
    }


    27.6.5.2. Определение собственной логики для добавления, обновления и удаления в Zend_Db_Table_Row

    Класс строки вызывает защищенные методы _insert(), _update() и _delete() до выполнения соответствующих операций INSERT, UPDATE и DELETE. Вы можете добавлять собственную логику в эти методы в созданном вами подклассе строки.

    Если нужно выполнение собственной логики в определенной таблице, и эта логика должна выполняться для каждой операции в этой таблице, то разумным решением может быть реализация собственной логики в методах insert(), update() и delete() вашего класса таблицы. Тем не менее, иногда может быть необходимым выполнять собственную логику в классе строки.

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

    Пример 27.124. Пример собственной логики в классе строки

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

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

    class MyLoggingRow extends Zend_Db_Table_Row_Abstract
    {
        protected function 
    _insert()
        {
            
    $log Zend_Registry::get('database_log');
            
    $log->info(Zend_Debug::dump($this->_data,
                                        
    "INSERT: $this->_tableClass",
                                        
    false)
                      );
        }
    }

    // $loggingEnabled - свойство, используемое для примера и зависящее
    // от конфигурации вашего приложения
    if ($loggingEnabled) {
        
    $bugs = new Bugs(array('rowClass' => 'MyLoggingRow'));
    } else {
        
    $bugs = new Bugs();
    }

    Пример 27.125. Пример класса строки, журналирующего добавляемые данные для нескольких таблиц

    Собственная логика может быть общей для нескольких таблиц. Вместо реализации одной и той же логики в каждом классе таблицы вы можете реализовать код этих действий в классе строки и использовать этот класс строки во всех ваших классах таблиц.

    В этом примере журналирующий код одинаков для всех классов таблиц.

    class MyLoggingRow extends Zend_Db_Table_Row_Abstract
    {
        protected function 
    _insert()
        {
            
    $log Zend_Registry::get('database_log');
            
    $log->info(Zend_Debug::dump($this->_data,
                                        
    "INSERT: $this->_tableClass",
                                        
    false)
                      );
        }
    }

    class 
    Bugs extends Zend_Db_Table_Abstract
    {
        protected 
    $_name 'bugs';
        protected 
    $_rowClass 'MyLoggingRow';
    }

    class 
    Products extends Zend_Db_Table_Abstract
    {
        protected 
    $_name 'products';
        protected 
    $_rowClass 'MyLoggingRow';
    }

    27.6.5.3. Определение инфлекции в Zend_Db_Table_Row

    Некоторые разработчики предпочитают, чтобы имя класса таблицы соответствовало имени таблицы в СУРБД с применением преобразования, называемого инфлекцией.

    Классы Zend_Db по умолчанию не производят инфлекцию. Читайте Раздел 27.5.12.4, «Определение инфлекции в Zend_Db_Table» для получения информации о причинах такого решения.

    Если вы предпочитаете использовать инфлекцию, то должны сами реализовать преобразование, переопределив метод _transformColumn() в своем классе строки и использовать этот класс при произведении запросов через ваш класс таблицы.

    Пример 27.126. Пример определения инфлекционного преобразования

    Это позволяет использовать в аксессорах преобразованный вариант имени столбца. Класс строки использует метод _transformColumn() для преобразования имени, которое используется в качестве "родного" имени столбца в таблице БД.

    class MyInflectedRow extends Zend_Db_Table_Row_Abstract
    {
        protected function 
    _transformColumn($key)
        {
            
    $nativeKey myCustomInflector($key);
            return 
    $nativeKey;
        }
    }

    class 
    Bugs extends Zend_Db_Table_Abstract
    {
        protected 
    $_name 'bugs';
        protected 
    $_rowClass 'MyInflectedRow';
    }

    $bugs = new Bugs();
    $row $bugs->createRow();

    // Используются имена столбцов в формате CamelCase, преобразующая функция
    // изменяет их представление на "родное"
    $row->bugDescription 'New description';

    Реализация функций для произведения инфлекционного преобразования возлагается на разработчика. Zend Framework не предоставляет для этих целей готовых функций.

    digg delicious meneame google twitter technorati facebook

    Comments

    Loading...