Pull to refresh

Использование Zend_Db_Table

Reading time3 min
Views2.6K
На работе пришлось столкнуться с очень не нравившейся мне ORM'кой собственного производства. Стал делать свою (ну не дурак ли, а? :)), наваял за 3 дня простенькую ORM, отображающую структуру таблиц на обьекты, не контроллируя типов. Итог получился примерно такой:
  • класс базы данных (относледовался от mysqli, pdo использовать было нельзя)
  • класс таблицы, хранящий в себе бд, и отвечающий за CRUD записей
  • класс записи, перенаправляющий методы CUD классу таблицы




Примерное использование:
<code class="php">$table = new ArticleTable();
$record = $table->fetchOneWhere("slug = 'hello'"); // получаем существующую запись
$record->name = 'Fucking Article!';
$record->save(); // вызывает insert/update в зависимости от того, новая ли это запись
$record = $table->create(); // создаем новую запись
$record->name = 'Fucking Article2!';
$record->slug = 'fucking_article';
// ...
$record->save();</code>

И что-то мне это очень сильно напомнило, а именно — Zend_Db: Zend_Db_Table / Zend_Db_Table_Row. Недолго думая — выкинул нафиг свою систему и залил в проект кусок Zend Framework'а (если нужно — потом скажу, какие именно файлы нужны для полноценной работы всего компонента Zend_Db), а также решил почитать, что сейчас вообще есть в этой Zend_Db, а есть, как оказалось — довольно много:
  • Хорошая абстракция работы с бд
  • Классы записи/таблицы
  • Поддержка fetch'инга связанных обьектов
  • Поддержка many-to-many связей (этого даже в Propel нет)

На самом деле — еще есть вещи, коотрые бы можно было добавить, чтобы они работали автоматически:
  • Валидаторы в зависимости от типов полей таблицы
  • Возможность сразу fetch'ить данные из нескольких таблиц (точнее — получить такие данные довольно легко, но вот разбрасывать их по разным обьектам и связывать эти обьекты сейчас нужно ручками, если я не ошибаюсь, но опять же — это проблем не составляет)

Вроде всё. Общее впечатление — просто замечательная система. Использовать легко и приятно. :)

Пример:
Сначала пойдут мои супертипы слоя (кто читал Patters of EAA — поймет):
<code class="php">class Db_Table extends Zend_Db_Table_Abstract {
  /**
   * @return Zend_Db_Table_Rowset_Abstract
   */
  public function fetchAllBy($key, $value) {
    $where = $this->getAdapter()->quoteInto("$key = ?", $value);
    return $this->fetchAll($where);
  }

  /**
   * @return Zend_Db_Table_Row_Abstract
   */
  public function fetchRowBy($key, $value) {
    $where = $this->getAdapter()->quoteInto("$key = ?", $value);
    return $this->fetchRow($where);
  }

  public function __call($name, $arguments) {
    if(strpos($name, 'fetchRowBy') === 0) {
      array_unshift($arguments, substr($name, 10));
      return call_user_func_array(array($this, 'fetchRowBy'), $arguments);
    }

    if(strpos($name, 'fetchAllBy') === 0) {
      array_unshift($arguments, substr($name, 10));
      return call_user_func_array(array($this, 'fetchAllBy'), $arguments);
    }

    throw new Exception("Undefined method $name");
  }
}

class Db_Record extends Zend_Db_Table_Row_Abstract {
}</code>

А теперь — пример использования:
<code class="php">class Item extends Db_Table {
  protected $_name = 'items';
  protected $_rowClass = 'ItemRecord';
  protected $_referenceMap = array(
      'Group' => array(
        'columns'       => 'groupid',
        'refTableClass' => 'Group',
        'refColumns'    => 'groupid',
      )
    );
}

class ItemRecord extends Db_Record {
}

class Group extends Db_Table {
  protected $_name = 'groups';
  protected $_rowClass = 'GroupRecord';
  protected $_dependentTables = array('Item');
}

class GroupRecord extends Db_Record {
}

$itemTable = new Item();
$item = $itemTable->fetchRowBySlug('hello');
$group = $item->findParentGroup();</code>

Согласитель — всё просто и удобно, не так ли?

Для заинтересовавшихся — очень советую проштудировать полностью главу о Zend_Db из документации Zend Framework'а. А также — мой пост про Zend_Db_Table, посвященный его улучшению (правда, я не знаю, насколько он сейчас актуален, проверять нет времени :( ).

Кросс-пост из моего блога
Tags:
Hubs:
+1
Comments47

Articles

Change theme settings