Chapter 6 - question about __get magic and objects

On pg. 106 we create the following function in /unit/IssueTest.php

public function testGetTypes()


	{


	  $options = Issue::model()->TypeOptions;


	  $this->assertTrue(is_array($options));  


	  $this->assertTrue(3 == count($options)); 


	  $this->assertTrue(in_array('Bug', $options));


	  $this->assertTrue(in_array('Feature', $options));


	  $this->assertTrue(in_array('Task', $options));


	}

I don’t understand how in OOP the function getTypeOptions() in model/Issue.php is called from /unit/IssueTest:

public function getTypeOptions()


{


	return array(


	    self::TYPE_BUG=>'Bug',


	    self::TYPE_FEATURE=>'Feature',


	    self::TYPE_TASK=>'Task',


	  );


}

In /unit/IssueTest.php we run this command:

$options = Issue::model()->TypeOptions;

I don’t see a property called “TypeOptions” in the model?? How does the above command get the array of bug, features, task?

Also, why does the model function have to be called? I would think that the property would be found like so:

$options = Issue::TypeOptions;

When you ask PHP for a property of an object, it will see if that property exists (and you have access to it, i.e. if it’s not protected or private) and if it doesn’t, it will call the function __get() on that object (if it exists).

Yii uses this __get() function to make getWhatever() functions in classes available as the property "whatever".

I don’t have the Yii source by hand, but it goes a little something like this:




class CComponent 

{

  function __get($property)

  {

     if (method_exists($this, 'get'.ucfirst($property))

     {

         return call_user_func(array($this, 'get'.ucfirst($property)));

     }

     // etc

  }

}



so now if there is a function getSomething(), you can use ->something, getWhatever() for ->whatever, etc.

The same mechanism is in place for set (using __set()), so if you do ->whatever=10, it will call ->setWhatever($value)

As for the Issue::typeOptions not existing, that’s a bit of tricky one to explain. The short answer is that the property is not defined as a static property and can thus not be accessed staticly (i.e. using :: ) but only dynamically.

You should google about static functions in PHP to get a grasp of the difference between static and dynamic functions/properties. This is too involved a subject to explain in a forum post.

Thanks ScallioXTX.

That makes sense. Sounds smart to me: Asking PHP for property, if I don’t have access to it run the __get function to pull it out of the object.