Using Zend_Db_Table

    At work I had to face my very own ORM'ka production. He began to do his own (well, isn’t he a fool, huh :)), in 3 days he got a simple ORM that displays the structure of tables on objects, without controlling the types. The result is something like this:
    • database class (inherited from mysqli, pdo could not be used)
    • a table class that stores a db and is responsible for CRUD records
    • a write class that redirects CUD methods to a table class

    Approximate use:
    $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';
    // ...

    And something reminded me very much, namely Zend_Db: Zend_Db_Table / Zend_Db_Table_Row. Without thinking twice, I threw my system nafig and uploaded a piece of Zend Framework into the project (if necessary - then I’ll tell you which files are needed for the entire Zend_Db component to work properly), and also decided to read what is now in this Zend_Db, but there are , as it turned out - quite a lot:
    • Good abstraction of working with obd
    • Record / Table Classes
    • Support for fetching related objects
    • Support for many-to-many connections (this is not even in Propel)

    In fact - there are still things that could be added so that they work automatically:
    • Validators depending on table field types
    • The ability to immediately fetch data from several tables (more precisely, it is quite easy to get such data, but scattering it on different objects and linking these objects now needs to be done with handles, if I’m not mistaken, but again this is not a problem)

    Look like that's it. The overall impression is just a wonderful system. Use is easy and pleasant. :)

    My supertypes of the layer will go first (those who read Patters of EAA will understand):
    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 {

    And now a usage example:
    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();

    Compromiser - everything is simple and convenient, isn't it?

    For those interested, I highly recommend that you read through the entire chapter on Zend_Db from the Zend Framework’s documentation. And also - my post about Zend_Db_Table , dedicated to its improvement (though I don’t know how relevant it is now, there’s no time to check :().

    Cross-post from my blog

    Also popular now: