I am implementing an OOP design using PHP. I wonder how PHP handles inheritance for its magic methods like __get and __set.
class Foo
{
protected $property1;
public function __get($name)
{
if ($name == "property1")
{
// do some logic
return $result; // may be null
}
return;
}
public function __set($name, $value)
{
if ($name == "property1")
{
// do some logic
return $result; // may be null
}
result;
}
}
Now for extending Foo
:
class Bar extends Foo
{
protected $property2;
public function __get($name)
{
if (($result = parent::__get($name)) !== null)
return $result; // may be null
if ($name == "property2")
{
// do some logic
return $result; // may be null
}
return;
}
public function __set($name, $value)
{
if (($result = parent::__set($name, $value)) !== null)
return $result; // may be null
if ($name == "property2")
{
// do some logic
return $result; // may be null
}
return;
}
}
As PHP returns null
as the result of a function with nothing to return... this may lead in ambiguity of whether the parent::__get()
or parent::__set()
returned null truely or returned with no value; and leads to overhead.
Now if PHP considers the static::_get()
and static::__set()
first and fall backs to the parent
versions on failure, this could be simplified as:
class Bar extends Foo
{
protected $property2;
public function __get($name)
{
if ($name = "property2")
{
// do some logic
return $result; // may be null
}
return;
}
public function __set($name, $value)
{
if ($name = "property2")
{
// do some logic
return $result; // may be null
}
return;
}
}
I can't test it on current implementation because the classes in context manipulates production, live database. Which is the correct implementation?
Thanks!
Use magic methods only as proxy methods. Your code will be much cleaner and you don't have to deal with problems caused by inheritance.
Simple example:
class Foo
{
protected $property1;
public function setProperty1($property1)
{
// do some logic
$this->property1 = $property1;
return $this;
}
public function getProperty1()
{
// do some logic
return $this->property1;
}
public function __get($name)
{
$method = 'get' . ucfirst($name);
if (method_exists($this, $method)) {
return $this->$method();
}
}
public function __set($name, $value)
{
$method = 'set' . ucfirst($name);
if (method_exists($this, $method)) {
$this->$method($value);
}
}
}
class Bar extends Foo
{
protected $property2;
public function setProperty2($property2)
{
// do some logic
$this->property2 = $property2;
return $this;
}
public function getProperty2()
{
// do some logic
return $this->property2;
}
}
Example call:
$bar = new Bar;
$bar->property1 = 'foo';
$bar->property2 = 'bar';
var_dump($bar);