Q:

PHP Visibility with Magic Methods __get & __set

I recently went to an interview and my code I supplied had magic functions to get and set variables. My code was as follows:
public function __get($name){
    try { 
        return $this->$name;
    } catch (Exception $e) { 
        throw new Exception('Trying to get a variable "'.$name.'" that does not exist.'); 
    }
}

In the interview the guy asked me about the visibility on my variables, I had private ones set but these were now accessible by using magic functions. Essentially I failed the interview on this point, so I wanted to understand more. I was following a tutorial from PHP Master and found a different __get, I have tried to break it but it seems to work, but in a strange way.
I call __get('test') to get my variable _test but if it is set to private it calls itself again and tells me that it cannot access __test. I do not really understand why it calls itself again.
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;

}

Can anyone give me some pointers on proper use of __get and __set when using visibility in a class and why this function would call itself again.
I have read the other posts here but I am still struggling with this concept.

A:

I just bumped into this question and there is a little thing that may be worth clarifying:

I do not really understand why it calls itself again.

The code is not calling itself again but trying to execute a custom getter if there is one defined. Let me break down the method execution:
public function __get($name)
{

As already explained in the other answers and here, the __get() magic method is called when you are trying to access a property that is not declared or not visible in the calling scope.
$field = '_' . strtolower($name);

if (!property_exists($this, $field)){
    throw new \InvalidArgumentException(
        "Getting the field '$field' is not valid for this entity"
    );
}

Here it just checks that a property with an underscore pre-appended exists in the class definition. If it doesn't, an exception is thrown.
$accessor = 'get' . ucfirst(strtolower($name));

Here it creates the name of the getter to call if it exists. Thus, if you try to access a property named email and there is a private member called _email the $accessor variable will now hold the 'getEmail' string.
return (method_exists($this, $accessor) && is_callable(array($this, $accessor))) ?
    $this->$accessor() : $this->$field;

The final part is a bit cryiptic, since many things are happening in one line:

method_exists($this, $accessor). Checks if the receiver ($this) has a method with $accessor name (in our example, getEmail).
is_callable(array($this, $accessor)). Checks that the getter can be called.
If both conditions are met, the custom getter is called and its return value is returned ($this->$accessor()). If not, the property contents 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

HTH

