If I use it like this (outside of a class):
$user_agent = $user->user_agent;
Method get_user_agent() is called in constructor.
Here magic __get calls method get_user_agent and not returning value of member variable user_agent.
How to avoid that?
class user
{
private $user_agent;
public function __get($key)
{
$value = null;
if(method_exists($this, "get_$key"))
{
$value = $this->{"get_$key"}();
}
else
{
$value = $this->$key;
}
return $value;
}
public function get_user_agent()
{
$this->user_agent = $_SERVER['HTTP_USER_AGENT'];
}
You forgot to return the value after setting it:
public function get_user_agent()
{
$this->user_agent = $_SERVER['HTTP_USER_AGENT'];
return $this->user_agent;
}
But this is actually quite confusing, because you would not expect a method prefixed with 'get' to assign/define anything first before returning it. That's what __set()
is for. In this case you probably even want to do it in the __construct()
method:
class user
{
private $user_agent;
public function __construct() {
$this->user_agent = $_SERVER['HTTP_USER_AGENT'];
}
public function __get($key) {
if(method_exists($this, "get_$key")) {
return $this->{"get_$key"}();
} else {
return isset($this->{$key}) ? $this->{$key} : null;
}
}
public function __set($var, $val) {
//only allow to set existent attributes
if( isset($this->{$var} ) ) {
$this->{$var} = $val;
}
}
public function get_user_agent() {
return $this->user_agent;
}
}
So the get-method is not the place to assign the attribute. In the example above, it is assign in the constructor. But you can change/assign it later if you want:
$user = new user(); //constructor-method is called, $user_agent is set now
But you can also set it yourself later on:
$user->user_agent = $_SERVER['HTTP_USER_AGENT']; //the magic __set()-method is called
echo 'Your user agent is: ' . $user->user_agent;