Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 88091
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 10, 20262026-05-10T22:30:19+00:00 2026-05-10T22:30:19+00:00

I’m working on creating a domain layer in Zend Framework that is separate from

  • 0

I’m working on creating a domain layer in Zend Framework that is separate from the data access layer. The Data Access Layer is composed to two main objects, a Table Data Gateway and a Row Data Gateway. As per Bill Karwin’s reply to this earlier question I now have the following code for my domain Person object:

class Model_Row_Person {     protected $_gateway;      public function __construct(Zend_Db_Table_Row $gateway)     {         $this->_gateway = $gateway;     }      public function login($userName, $password)     {      }      public function setPassword($password)     {      } } 

However, this only works with an individual row. I also need to create a domain object that can represent the entire table and (presumably) can be used to iterate through all of the Person’s in the table and return the appropriate type of person (admin, buyer, etc) object for use. Basically, I envision something like the following:

class Model_Table_Person implements SeekableIterator, Countable, ArrayAccess {     protected $_gateway;      public function __construct(Model_DbTable_Person $gateway)     {         $this->_gateway = $gateway;     }      public function current()     {         $current = $this->_gateway->fetchRow($this->_pointer);          return $this->_getUser($current);     }      private function _getUser(Zend_Db_Table_Row $current)     {         switch($current->userType)         {             case 'admin':                 return new Model_Row_Administrator($current);                 break;             case 'associate':                 return new Model_Row_Associate($current);                 break;         }     } } 

Is this is good/bad way to handle this particular problem? What improvements or adjustments should I make to the overall design?

Thanks in advance for your comments and criticisms.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. 2026-05-10T22:30:19+00:00Added an answer on May 10, 2026 at 10:30 pm

    I had in mind that you would use the Domain Model class to completely hide the fact that you’re using a database table for persistence. So passing a Table object or a Row object should be completely under the covers:

    <?php require_once 'Zend/Loader.php'; Zend_Loader::registerAutoload();  $db = Zend_Db::factory('mysqli', array('dbname'=>'test',     'username'=>'root', 'password'=>'xxxx')); Zend_Db_Table_Abstract::setDefaultAdapter($db);  class Table_Person extends Zend_Db_Table_Abstract {     protected $_name = 'person'; }  class Model_Person {     /** @var Zend_Db_Table */     protected static $table = null;      /** @var Zend_Db_Table_Row */     protected $person;      public static function init() {         if (self::$table == null) {             self::$table = new Table_Person();         }     }      protected static function factory(Zend_Db_Table_Row $personRow) {         $personClass = 'Model_Person_' . ucfirst($personRow->person_type);         return new $personClass($personRow);     }      public static function get($id) {         self::init();         $personRow = self::$table->find($id)->current();         return self::factory($personRow);     }      public static function getCollection() {         self::init();         $personRowset = self::$table->fetchAll();         $personArray = array();         foreach ($personRowset as $person) {             $personArray[] = self::factory($person);         }         return $personArray;     }      // protected constructor can only be called from this class, e.g. factory()     protected function __construct(Zend_Db_Table_Row $personRow) {         $this->person = $personRow;     }      public function login($password) {         if ($this->person->password_hash ==             hash('sha256', $this->person->password_salt . $password)) {             return true;         } else {             return false;         }      }      public function setPassword($newPassword) {         $this->person->password_hash = hash('sha256',             $this->person->password_salt . $newPassword);         $this->person->save();     } }  class Model_Person_Admin extends Model_Person { } class Model_Person_Associate extends Model_Person { }  $person = Model_Person::get(1); print 'Got object of type '.get_class($person).'\n'; $person->setPassword('potrzebie');  $people = Model_Person::getCollection(); print 'Got '.count($people).' people objects:\n'; foreach ($people as $i => $person) {     print '\t$i: '.get_class($person).'\n'; } 

    ‘I thought static methods were bad which is why I was trying to create the table level methods as instance methods.’

    I don’t buy into any blanket statement that static is always bad, or singletons are always bad, or goto is always bad, or what have you. People who make such unequivocal statements are looking to oversimplify the issues. Use the language tools appropriately and they’ll be good to you.

    That said, there’s often a tradeoff when you choose one language construct, it makes it easier to do some things while it’s harder to do other things. People often point to static making it difficult to write unit test code, and also PHP has some annoying deficiencies related to static and subclassing. But there are also advantages, as we see in this code. You have to judge for yourself whether the advantages outweigh the disadvantages, on a case by case basis.

    ‘Would Zend Framework support a Finder class?’

    I don’t think that’s necessary.

    ‘Is there a particular reason that you renamed the find method to be get in the model class?’

    I named the method get() just to be distinct from find(). The ‘getter’ paradigm is associated with OO interfaces, while ‘finders’ are traditionally associated with database stuff. We’re trying to design the Domain Model to pretend there’s no database involved.

    ‘And would you use continue to use the same logic to implement specific getBy and getCollectionBy methods?’

    I’d resist creating a generic getBy() method, because it’s tempting to make it accept a generic SQL expression, and then pass it on to the data access objects verbatim. This couples the usage of our Domain Model to the underlying database representation.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 113k
  • Answers 113k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer Here's your code, fixed up and working: import sys number… May 11, 2026 at 10:00 pm
  • Editorial Team
    Editorial Team added an answer I think you're misunderstanding whats happening with the ContextLifeTimeManager. By… May 11, 2026 at 10:00 pm
  • Editorial Team
    Editorial Team added an answer You can't detect a variable's name directly, but you can… May 11, 2026 at 10:00 pm

Related Questions

I ran into a problem. Wrote the following code snippet: teksti = teksti.Trim() teksti
I am currently running into a problem where an element is coming back from
Seemingly simple, but I cannot find anything relevant on the web. What is the
Configuring TinyMCE to allow for tags, based on a customer requirement. My config is
Is it possible to replace javascript w/ HTML if JavaScript is not enabled on

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.