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.

Sonny
  • 8,204
  • 7
  • 63
  • 134
  • 1
    What are you doing in your code that you need to instantiate multiple instances of the same table in the same request? – Gordon Apr 14 '10 at 22:14
  • 2
    *(reference)* http://sourcemaking.com/design_patterns/singleton – Gordon Apr 14 '10 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! – Sonny Apr 14 '10 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. – Gordon Apr 15 '10 at 07: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. – Sonny Apr 15 '10 at 14:36

1 Answers1

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.

timdev
  • 61,857
  • 6
  • 82
  • 92
  • 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. – Sonny Apr 14 '10 at 23:01
  • 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. – timdev Apr 14 '10 at 23:05
  • 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() – SoWhat Jun 11 '13 at 04:41
  • @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. – timdev Jun 12 '13 at 19:13
  • 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 – SoWhat Jun 13 '13 at 02:48