3

I have found myself doing this in my code to 'cache' the work done when instantiating my Zend_Db_Table models:

if (Zend_Registry::isRegistered('x_table')) {
    $x_table = Zend_Registry::get('x_table');
} else {
    $x_table = new Default_Model_DbTable_X;
    Zend_Registry::set('x_table', $x_table);
}

It bothered me that this method isn't very DRY and it dawned on me today that a singleton pattern would probably be a better way to do this. Problem is, I've never written a singleton class. When I did some web searches, I found some offhand comments about Zend_Db_Table singletons, but no real examples.

I already have meta-data caching configured.

  1. How do I make my Zend_Db_Table models singletons?
  2. Are there pitfalls or downsides?

Edit: My reason for thinking a singleton was the answer is that I thought I could simply have the following calls in my code $x_table = new Default_Model_DbTable_X; and the single instance would be returned if it existed. If this is possible, I would prefer that solution.

5
  • 1
    What are you doing in your code that you need to instantiate multiple instances of the same table in the same request? Commented Apr 14, 2010 at 22:14
  • 2
    (reference) sourcemaking.com/design_patterns/singleton Commented Apr 14, 2010 at 22:17
  • I am building a CMS and the tables contain content. Content blocks can be put into a page, and the page may have more than one of the same type of block in it. Thanks for the reference! Commented Apr 14, 2010 at 22:56
  • you're welcome, but I still don't get why you need multiple instances of the same table instead of just passing around the first instance and doing multiple queries on it. Commented Apr 15, 2010 at 7:17
  • @Gordon - Sorry, I didn't answer your question correctly. I don't need multiple instances, that's what my code above is trying to mitigate. I (check for|store) the instance in the registry, which may or may not be there. My post is basically asking for a better way. Commented Apr 15, 2010 at 14:36

1 Answer 1

3

Why not just manage the DbTables in some sensible place? If there's no sensible place, create a DbTableManager class. Something like:

<?PHP
class DbTableMgr {

  protected $_tables;

  public function getTable($classname){
    if ( empty($this->_tables[$name]) ){
      //assuming some things about class names for the sake of brevity elsewhere...
      $classname = 'Default_Model_DbTable_',ucfirst(strtolower($classname));

      $this->_tables[$name] = new $classname; 
    }
    return $this->_tables[$name];  
  }
}

Initialize the manager in your bootstrap and stick it in the registry.

Then:

<?PHP
//in a galaxy far, far, away
$dbtFoo = Zend_Registry::get('dbtMgr')->getTable('Foo');

So, you lazy-load the dbTable objects, and enforce a singleton-like behavior.

You could make the above static in various ways, if you wanted to.

Sign up to request clarification or add additional context in comments.

5 Comments

Your Zend_Registry method looks good, but I'm intrigued by what you meant by "sensible place". It sounds like you're implying that the Zend_Registry is a second-best solution.
Zend_Registry is fine for this kind of thing. I just meant that, depending on the application design, there might be a more sensible place to implement the dbTableManager stuff. But if you're not sure, there's nothing wrong with just making a class like I've shown, and sticking that into the registry while bootstrapping your database stuff.
okay this is an old question but m curious. Why not just make it a signleton. If nothing else it adds convinience. UserTable::getInstance()->getUsers()
@Somesh Mukherjee - You could do that too, but in that case you'd need to add another layer to your class hierarchy to provide the singleton behavior for all *Table classes. Zend_Registry is already there, and accomplishes essentially the same thing.
okay that is true. but i still think that's how Zend Tables should have been. The singeton pattern makes more sense than having a new object

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.