I just came across this question, and there is something that may be useful to clarify:
I don’t understand why he calls himself again.
The code does not call itself again, but tries to execute a custom getter, if defined. Let me break up the execution of a method:
public function __get($name) {
As already explained in other answers and here , the __get () magic method is called when you try to access a property that is not declared or invisible in the call area.
$field = '_' . strtolower($name); if (!property_exists($this, $field)){ throw new \InvalidArgumentException( "Getting the field '$field' is not valid for this entity" ); }
Here, it simply verifies that a property with a preliminary underscore exists in the class definition. If this is not the case, an exception is thrown.
$accessor = 'get' . ucfirst(strtolower($name));
Here it creates the name of the recipient to call if it exists. Thus, if you try to access a property named email , and there is a private member named _email , the $accessor variable will now contain the string 'getEmail' .
return (method_exists($this, $accessor) && is_callable(array($this, $accessor))) ? $this->$accessor() : $this->$field;
The last part is a bit critical, as many things happen on one line:
method_exists($this, $accessor) . Checks if the receiver ( $this ) has a method called $accessor (in our example getEmail ).is_callable(array($this, $accessor)) . Checks what getter can be called .- If both conditions are met, a custom getter is called and its return value is returned (
$this->$accessor() ). If not, the contents of the property are returned ( $this->$field ).
As an example, consider this class definition:
class AccessorsExample { private $_test1 = "One"; private $_test2 = "Two"; public function getTest2() { echo "Calling the getter\n"; return $this->_test2; } public function __get($name) { $field = '_' . strtolower($name); if (!property_exists($this, $field)){ throw new \InvalidArgumentException( "Getting the field '$field' is not valid for this entity" ); } $accessor = 'get' . ucfirst(strtolower($name)); return (method_exists($this, $accessor) && is_callable(array($this, $accessor))) ? $this->$accessor() : $this->$field; } }
and then run:
$example = new AccessorsExample(); echo $example->test1 . "\n"; echo $example->test2 . "\n";
You should see:
One Calling the getter Two
NTN