Well I am trying to design a registry class for my project. The Registry class itself is pretty much a singleton class, it stores certain objects that can be retrieved and used in any scope of application. What differentiates this registry class from other available framework's is that my registry class stores system objects upon instantiation. It proves to be somewhat of a challenge to me since my programming skills aint that advanced yet. Here's the code I have so far:

class Registry extends ArrayObject{
  // The registry class used to store objects available for entire application

  protected $reserved = array("system", "path", "database", "cookies", "session", "currentuser", "usergroup", "settings", "page", "template", "request", "input", "action", "plugin", "debug");
  protected static $instance;

  public function __construct($props = ""){
     // Construct the Registry object

 $flags = parent::ARRAY_AS_PROPS;
 if($props instanceof System) $props = self::initialize($props);
     if(!is_array($props)) $props = array($props);
 parent::__construct($props, $flags); 
  }

  protected static function initialize($system){
     // Initialize the Registry Object with basic properties
	 $init = array("system" => $system, 
	              "path" => $system->path, 
			      "database" => $system->db, 
				  "cookies" => $system->cookies, 
				  "session" => $system->session,
                  "currentuser" => $system->user,
                  "usergroup" => $system->usergroup, 
				  "settings" => $system->settings, 
				  "page" => $system->page, 
				  "template" => $system->template, 
				  "request" => $system->request, 
				  "input" => $system->input, 
				  "plugin" => $system->plugin, 
				  "debug" => $system->debug);
	 return $init;
  }

  public static function getinstance(){
     // Return all objects assigned in the registry singleton class
	 if(!self::$instance) self::instance = new Registry();
	 return self::$instance;
  }

  public static function assign($key, $val, $overwrite == TRUE){
     // Assign objects to registry in class member methods
	 if($overwrite == FALSE and self::$instance->exist($key) == TRUE) throw new Exception("Cannot overwrite registered object");
	 else self::$instance->offsetSet($key, $val);
  }

  public static function retrieve($key){
     // Retrieve objects from registry in class member methods
	 if(!self::$instance->exist($key)) throw new Exception("Cannot retrieve an unregistered object");
	 return self::$instance->offsetGet($key);
  }

  public static function remove($key){
     // Remove objects in registry from class member methods
	 if(!in_array($key, $reserved)) self::$instance->offsetUnset($key);	 
  }

  public function exist($key){
     return array_key_exists($key, $this);
  }

  public function clear(){
     // Unset all registered objects, except for system objects
	 foreach(self::$instance as $key => $val){
	    self::remove($key);
	 }
  }    
}

So I borrowed some ideas from Zend Framework's Registry class, which extends the ArrayObject parent class to make it iterable. Please take a look at this class I designed and lemme know what problems you see from it. I'd appreciate comments and criticism very much.

Lord Yggdrasill

    I just realized that my registry class had a problem that the system objects aint assigned to the static self::$instance correctly. I modified the script and this time it should at least work. Please gimme some comments, Id appreciate any help and criticism here:

    <?php
    
    class Registry{
      // The registry class used to store objects available for entire application
    
      protected $reserved = array("system", "path", "database", "cookies", "session", "currentuser", "usergroup", "settings", "page", "template", "request", "input", "plugin", "debug");
      protected static $instance;
    
      public function __construct($props = ""){
         // Construct the Registry object
    
     $flags = parent::ARRAY_AS_PROPS;
     if($props instanceof System) $props = self::initialize($props);
     if(!is_array($props)) $props = array($props);
     self::$instance = new ArrayObject($props, $flags); 
      }
    
      public function __clone(){
         // Clone of Registry object is disabled
    	 return FALSE;
      }
    
      protected static function initialize($system){
         // Initialize the Registry Object with basic properties
    	 $init = array("system" => $system, 
    	               "path" => $system->path, 
    			       "database" => $system->db, 
    				   "cookies" => $system->cookies, 
    				   "session" => $system->session,
                       "currentuser" => $system->user,
                       "usergroup" => $system->usergroup, 
    				   "settings" => $system->settings, 
    				   "page" => $system->page, 
    				   "template" => $system->template, 
    				   "request" => $system->request, 
    				   "input" => $system->input, 
    				   "plugin" => $system->plugin, 
    				   "debug" => $system->debug);
    	 return $init;
      }
    
      public static function getinstance(){
         // Return all objects assigned in the registry singleton class
    	 if(!self::$instance) self::instance = new Registry();
    	 return self::$instance;
      }
    
      public static function exist($key){
         return array_key_exists($key, self::$instance);
      }
    
      public static function assign($key, $val, $overwrite == TRUE){
         // Assign objects to registry in class member methods
    	 if($overwrite == FALSE and self::exist($key) == TRUE) throw new Exception("Cannot overwrite registered object");
    	 else self::$instance->offsetSet($key, $val);
      }
    
      public static function retrieve($key){
         // Retrieve objects from registry in class member methods
    	 if(!self::exist($key)) throw new Exception("Cannot retrieve registered object");
    	 return self::$instance->offsetGet($key);
      }
    
      public static function remove($key){
         // Remove objects in registry from class member methods
    	 if(!in_array($key, $reserved)) self::$instance->offsetUnset($key);	 
      }
    
      public function clear(){
         // Unset all registered objects, except for system objects
    	 foreach(self::$instance as $key => $val){
    	    self::remove($key);
    	 }
      }    
    } ?>

      Hmm... have you tested this? You have a typographical error on this line:

      public static function assign($key, $val, $overwrite == TRUE){

      That is, the "==" should be "=".

      Also, this:

      $overwrite == FALSE and self::exist($key) == TRUE

      could be simplified to:

      !$overwrite && self::exist($key)

      Usually if you really do want to explicitly compare with the boolean literals, it would be because you are using === or !== instead of just == or !=.

        laserlight;11006258 wrote:

        Hmm... have you tested this? You have a typographical error on this line:

        public static function assign($key, $val, $overwrite == TRUE){

        That is, the "==" should be "=".

        Also, this:

        $overwrite == FALSE and self::exist($key) == TRUE

        could be simplified to:

        !$overwrite && self::exist($key)

        Usually if you really do want to explicitly compare with the boolean literals, it would be because you are using === or !== instead of just == or !=.

        Oh thanks, did not realize I made a typo. I am indeed used to writing conditional code like if($var == FALSE), guess it is a bad habit I should get rid of. Are there any other issues you find or any more comments you can make? Id appreciate any advices here.
        🙂

          Lord Yggdrasill;11006259 wrote:

          Oh thanks, did not realize I made a typo. I am indeed used to writing conditional code like if($var == FALSE), guess it is a bad habit I should get rid of. Are there any other issues you find or any more comments you can make? Id appreciate any advices here.
          🙂

          I don't know if it's a "bad habit" or not. Some might argue it makes for more readable code to use the explicit comparison to a Boolean -- others might not. 🙂

            NogDog;11006269 wrote:

            I don't know if it's a "bad habit" or not. Some might argue it makes for more readable code to use the explicit comparison to a Boolean -- others might not. 🙂

            I only do explicit comparisons when I'm using strict comparison (===) Otherwise I think it makes it not as readable because of the loose typing in PHP. The variable might not be false but evaluate to false, and I think explicitly doing loose comparisons doesn't properly represent what is happening. Where as !$var says (to me at least) that if $var can be loosely typed to FALSE then do something.

              Derokorian;11006270 wrote:

              I only do explicit comparisons when I'm using strict comparison (===) Otherwise I think it makes it not as readable because of the loose typing in PHP. The variable might not be false but evaluate to false, and I think explicitly doing loose comparisons doesn't properly represent what is happening. Where as !$var says (to me at least) that if $var can be loosely typed to FALSE then do something.

              Can't say that I see that, personally, but it's definitely a "personally" thing. I've been using PHP for many years and basically assume loose-typing is going on unless I see the [not] identical operator. But as with any style choice, your mileage will vary from mine, and your choice is as good as mine (unless working in a group situation where one or the other is specified as the "correct" style).

              I'm not saying I don't use the "!" operator, but I have found times where I've changed it to an "== FALSE" because the expression involved had gotten convoluted enough that I felt it was clearer that way.

              PS: One thing I do try to do these days is separate the "!" operator so that it stands out:

              if( ! $expression) {
              // instead of:
              if(!$expression) {
              

                Yeah its definitely a personal thing. I've never developed PHP in a group situation only other languages heh. I think the fact that my full time job involves main C# and VB.NET makes it a little different since I switch between PHP on weekends and those during the majority of my coding time. In fact I find myself forcing more strict control of my variables through classes when working in PHP now-a-days.

                  Lord Yggdrasill wrote:

                  Are there any other issues you find or any more comments you can make?

                  I notice that you wrote:

                  if($props instanceof System) $props = self::initialize($props);
                      if(!is_array($props)) $props = array($props);

                  It seems to me that you intended to write:

                  if($props instanceof System) $props = self::initialize($props);
                  elseif(!is_array($props)) $props = array($props);
                  NogDog wrote:

                  Some might argue it makes for more readable code to use the explicit comparison to a Boolean -- others might not.

                  I think you're one of the first experienced programmers I've met who has ventured to suggest that the explicit comparison may make the code more readable instead of less readable. Then again, most of the ("real") programmers I come into contact with had some kind of computer science/engineering background where they were brought up on boolean algebra, whereas I recall you came from a more interesting background, so perhaps that gives you a different way of looking at code 🙂

                  NogDog wrote:

                  I have found times where I've changed it to an "== FALSE" because the expression involved had gotten convoluted enough that I felt it was clearer that way.

                  Why not break it up into separate statements or use a helper function instead? I daresay that these will improve readability, compared to making the expression unnecessarily verbose with an explicit comparison to a boolean literal.

                    Write a Reply...