KevinM1 Posted March 28, 2008 Share Posted March 28, 2008 I'm currently trying my hand at creating Registry classes that are very similar to those found in the Zandstra book. I thought it was a good idea to remove some of the initialization from the constructors and put them in their respective getInstance() methods. So, I have the following: Base Registry class: <?php abstract class MP_base_Registry{ private final function __construct(){} abstract protected function get($key); abstract protected function set($key, $value); } ?> RequestRegistry: <?php class MP_base_RequestRegistry extends MP_base_Registry{ private static $instance; private $requests = array(); static function getInstance(){ if(!self::$instance){ self::$instance = new self(); } return self::$instance; } protected function get($key){ return $this->requests[$key]; } protected function set($key, $value){ $this->requests[$key] = $value; } static function getRequest(){ return self::$instance->get('request'); } static function setRequest(MP_controller_Request $request){ self::$instance->set('request', $request); } } ?> SessionRegistry (unfinished as I have a question about it): <?php class MP_base_SessionRegistry extends MP_base_Registry{ private static $instance; static function getInstance(){ if(!self::$instance){ session_start(); self::$instance = new self(); } return self::$instance; } protected function get($key){ return $_SESSION[__CLASS__][$key]; } protected function set($key, $value){ $_SESSION[__CLASS__][$key] = $value; } /* inquire about the Complex $complex in Zandstra's book */ } ?> And, finally, ApplicationRegistry: <?php class MP_base_ApplicationRegistry extends MP_base_Registry{ private static $instance; private $values = array(); private $appFile = "data/applicationRegistry.txt"; private $isDirty = false; static function getInstance(){ if(!self::$instance){ self::$instance = new self(); $this->doReload(); } return self::$instance; } function __destruct(){ if($this->isDirty){ $this->save(); } } static function reload(){ self::instance->doReload(); } private function doReload(){ if(!file_exists($this->appFile)){ return false; } $serialized = file_get_contents($this->appFile, true); $fileContents = unserialize($serialized); if(is_array($fileContents)){ $fileContents = array_merge($fileContents, $this->values); $this->values = $fileContents; return true; } return false; } private function save(){ $saveData = serialize($this->values); file_put_contents($this->appFile, $saveData, FILE_USE_INCLUDE_PATH); $this->isDirty = false; } protected function get($key){ return $this->values[$key]; } protected function set($key, $value){ $this->values[$key] = $value; $this->isDirty = true; } static function isEmpty(){ return empty(self::$instance->values); } /*add static functions or use magic __get() and __set() to obtain/set specific data */ } ?> Okay, with that in place, here are my questions: 1. In SessionRegistry, Zandstra creates two publically available static methods that get and set session info. They look like this: <?php function getComplex(){ return self::$instance->get('complex'); } function setComplex(Complex $complex){ self::$instance->set('complex', $complex); } ?> I haven't read much further in the book, so I'm not sure if this is addressed later on, but is the Complex datatype there just as a hypothetical? Or is he suggesing that things saved in a session should all have the same base class (in this case, a class named Complex)? 2. In ApplicationRegistry, he (and thus, my code) seem to switch from using self::$instance and $this->something. This is a bit confusing. I realize that the former represents accessing something as part of a class, and the latter means actually accessing the object. That said, the object in question is actually referred to by itself via $instance. So, wouldn't accessing the private properties of the class have to be done like self::$instance->values, or something along those lines? 3. Are there any pitfalls you can see in me forcing the constructors to be empty? I figure that since it's basically a large singleton, the getInstance() method will always be called whenever one wants access to a Registry. Why not put the initialization processes in there when the first instance is created? Quote Link to comment https://forums.phpfreaks.com/topic/98324-registry-questions/ Share on other sites More sharing options...
Daniel0 Posted April 1, 2008 Share Posted April 1, 2008 Re. 1: You'd have to figure out what the Complex class is. Apparently he thinks that it should have it's own getter and setter methods. Re. 2: Doing self::$instance->something instead of $this->something would in this case be the same seeing as self::$instance === $this in this case. Re. 3: It depends on whether you need it done each time you get the instance or the first time you get the instance (i.e. when it's created). Also, I'd modify your MP_base_Registry class to look like this: <?php abstract class MP_base_Registry{ protected static $instance; static public function getInstance(){ if(!self::$instance){ session_start(); self::$instance = new self(); } return self::$instance; } private final function __construct(){} abstract protected function get($key); abstract protected function set($key, $value); } ?> Then you can always override the getInstance() method in child classes if you need specialized behavior. Quote Link to comment https://forums.phpfreaks.com/topic/98324-registry-questions/#findComment-506261 Share on other sites More sharing options...
aschk Posted April 1, 2008 Share Posted April 1, 2008 Not sure I agree 100% with daniel's implementation of the Base_Registry, as he appears to have put session_start() inside there, which should ONLY occur in the Session_Registry object... 1) Complex is basically just a complex object. In the case of the session registry, I would imagine 1 such object to be a "User", i.e. setUser(User $user), and getUser() 2) self::$instance is used with static public functions (in case you hadn't noticed) which obviously (because they're static) don't have a $this reference. Hence the need to utilise the internal static variable $instance. 3) See Daniel0's example, as I'm pretty sure he's covered this correctly. p.s. NOW i know how to get singletons in a parent class, DOH! Quote Link to comment https://forums.phpfreaks.com/topic/98324-registry-questions/#findComment-506373 Share on other sites More sharing options...
Daniel0 Posted April 1, 2008 Share Posted April 1, 2008 Not sure I agree 100% with daniel's implementation of the Base_Registry, as he appears to have put session_start() inside there, which should ONLY occur in the Session_Registry object... Actually, I didn't even notice that. I just copied the method verbatim from one of his classes. I certainly didn't mean to do so. Quote Link to comment https://forums.phpfreaks.com/topic/98324-registry-questions/#findComment-506503 Share on other sites More sharing options...
KevinM1 Posted April 1, 2008 Author Share Posted April 1, 2008 Ah, great, thanks guys! I thought I was more or less on the right track, but it's nice to get confirmation. Regarding question 3, specifically something done once vs. each time an instance is created/assigned -- does calling session_start() after a session is already in place destroy the current session? Or does it just not do anything? Quote Link to comment https://forums.phpfreaks.com/topic/98324-registry-questions/#findComment-506520 Share on other sites More sharing options...
Daniel0 Posted April 1, 2008 Share Posted April 1, 2008 P.S.: What happened to the 'Topic Solved' button? I loved that addon to the forums. It disappeared after the upgrade to 1.1.4. I seriously don't know what's taking them so long to install the modification again. Quote Link to comment https://forums.phpfreaks.com/topic/98324-registry-questions/#findComment-506524 Share on other sites More sharing options...
KevinM1 Posted April 1, 2008 Author Share Posted April 1, 2008 Damn, that was a fast reply! Also, I'm bumping this just to ensure that either of you can see my last edited post. Quote Link to comment https://forums.phpfreaks.com/topic/98324-registry-questions/#findComment-506528 Share on other sites More sharing options...
Daniel0 Posted April 1, 2008 Share Posted April 1, 2008 Regarding question 3, specifically something done once vs. each time an instance is created/assigned -- does calling session_start() after a session is already in place destroy the current session? Or does it just not do anything? <?php session_start(); session_start(); ?> Notice: A session had already been started - ignoring session_start() in /var/www/test.php on line 3 Quote Link to comment https://forums.phpfreaks.com/topic/98324-registry-questions/#findComment-506530 Share on other sites More sharing options...
KevinM1 Posted April 1, 2008 Author Share Posted April 1, 2008 Ah, nice. It's possible to either catch that notice in an Exception, or otherwise dispose of it, right? Quote Link to comment https://forums.phpfreaks.com/topic/98324-registry-questions/#findComment-506553 Share on other sites More sharing options...
Daniel0 Posted April 1, 2008 Share Posted April 1, 2008 Well, the best way to ensure that there are no notices is to code properly Quote Link to comment https://forums.phpfreaks.com/topic/98324-registry-questions/#findComment-506573 Share on other sites More sharing options...
KevinM1 Posted April 1, 2008 Author Share Posted April 1, 2008 Well, the best way to ensure that there are no notices is to code properly Oh, sure, I could go that way.... Quote Link to comment https://forums.phpfreaks.com/topic/98324-registry-questions/#findComment-506638 Share on other sites More sharing options...
aschk Posted April 2, 2008 Share Posted April 2, 2008 You can use the set_error_handler() function to catch errors (like notices) and log them somewhere I suppose. never implemented this as a feature so i'm not 100% sure on that. Quote Link to comment https://forums.phpfreaks.com/topic/98324-registry-questions/#findComment-507592 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.