这样做会被认为是良好的做法......
我有A级,其定义如下:
class A{
private $_varOne;
private $_varTwo;
private $_varThree;
public $varOne;
public function __get($name){
$fn_name = 'get' . $name;
if (method_exists($this, $fn_name)){
return $this->$fn_name();
}else if(property_exists('DB', $name)){
return $this->$name;
}else{
return null;
}
}
public function __set($name, $value){
$fn_name = 'set' . $name;
if(method_exists($this, $fn_name)){
$this->$fn_name($value);
}else if(property_exists($this->__get("Classname"), $name)){
$this->$name = $value;
}else{
return null;
}
}
public function get_varOne(){
return $this->_varOne . "+";
}
}
$A = new A();
$A->_varOne; //For some reason I need _varOne to be returned appended with a +
$A->_varTwo; //I just need the value of _varTwo
为了不创建4个set和4个get方法,我使用了魔术方法来为我需要的属性调用受尊重的getter,或者只返回属性的值而不做任何改变。这可以认为是好的做法?
答案 0 :(得分:7)
不了解最佳做法,但是当您需要延迟加载属性时__get非常有用,例如:获取它时涉及复杂的钙化或数据库查询。此外,php提供了一种优雅的方法来缓存响应,只需创建一个具有相同名称的对象字段,这样就可以防止再次调用getter。
class LazyLoader
{
public $pub = 123;
function __get($p) {
$fn = "get_$p";
return method_exists($this, $fn) ?
$this->$fn() :
$this->$p; // simulate an error
}
// this will be called every time
function get_rand() {
return rand();
}
// this will be called once
function get_cached() {
return $this->cached = rand();
}
}
$a = new LazyLoader;
var_dump($a->pub); // getter not called
var_dump($a->rand); // getter called
var_dump($a->rand); // once again
var_dump($a->cached); // getter called
var_dump($a->cached); // getter NOT called, response cached
var_dump($a->notreally); // error!
答案 1 :(得分:3)
这可以算是一种好的做法吗?
取决于你要解决的问题,但总的来说,没有。我来自思想学派,魔术方法只应用于解决现有问题,这些问题不能用任何其他实际方法解决,而不是用它们作为设计的基础。
你所做的很多事情都可以通过真正的getter / setter来处理。 PHP没有真正的属性,所以强迫它们上课是绝对不利的。
答案 2 :(得分:2)
你来自Java,不是吗?
无论如何,如果你只是不加选择地设置这些属性,只需将它们公之于众。如果除了分配和读取变量之外,还需要对数据执行其他操作,请使用__get,__ set和私有属性。
此外,您可能会看到通常会说魔术方法会妨碍性能等,但这应该只是在高使用率情况下才会引起关注 - 通常瓶颈是磁盘I / O,数据库或在某些情况下,内存/ CPU密集型操作
答案 3 :(得分:1)
不,这不是因为这些魔术方法是拦截器,可以在PHP抛出错误之前处理对不可访问属性的任何调用。它们不能替代正确的吸气剂和制定者。
They also behave differently as stated in the Manual:
由于PHP处理赋值运算符的方式,忽略__set()的返回值。类似地,在将分配链接在一起时,永远不会调用__get(): $ a = $ obj-> b = 8;
他们也是slower to execute with a significant performance impact。你的API也会变得不那么透明,因为所有神奇地做某事的东西都令人费解。