rfc*_*484 121 php magic-methods
可能重复:
魔术方法是PHP的最佳实践吗?
这些都是简单的例子,但想象一下你的班级中有两个以上的属性.
什么是最佳做法?
a)使用__get和__set
class MyClass {
private $firstField;
private $secondField;
public function __get($property) {
if (property_exists($this, $property)) {
return $this->$property;
}
}
public function __set($property, $value) {
if (property_exists($this, $property)) {
$this->$property = $value;
}
}
}
$myClass = new MyClass();
$myClass->firstField = "This is a foo line";
$myClass->secondField = "This is a bar line";
echo $myClass->firstField;
echo $myClass->secondField;
/* Output:
This is a foo line
This is a bar line
*/
Run Code Online (Sandbox Code Playgroud)
b)使用传统的二传手和吸气剂
class MyClass {
private $firstField;
private $secondField;
public function getFirstField() {
return $this->firstField;
}
public function setFirstField($firstField) {
$this->firstField = $firstField;
}
public function getSecondField() {
return $this->secondField;
}
public function setSecondField($secondField) {
$this->secondField = $secondField;
}
}
$myClass = new MyClass();
$myClass->setFirstField("This is a foo line");
$myClass->setSecondField("This is a bar line");
echo $myClass->getFirstField();
echo $myClass->getSecondField();
/* Output:
This is a foo line
This is a bar line
*/
Run Code Online (Sandbox Code Playgroud)
在本文中:http://blog.webspecies.co.uk/2011-05-23/the-new-era-of-php-frameworks.html
作者声称使用魔法不是一个好主意:
首先,当时使用PHP的魔术函数(__get,__ call等)非常受欢迎.从初看起来没有任何问题,但它们实际上非常危险.它们使API不清楚,无法自动完成,最重要的是它们很慢.他们的用例是破解PHP来做他们不想做的事情.它奏效了.但是发生了坏事.
但我想听听更多关于此的意见.
Mat*_*oli 154
我过去一直都在你的情况.然后我去寻找魔术方法.
这是一个错误,你问题的最后一部分说明了一切:
@property
PHPDoc的注解,但是需要保持他们:相当疼痛)getXXX()
不仅返回私有属性而且执行真正的逻辑.你有相同的命名.例如,您有$user->getName()
(返回私有属性)和$user->getToken($key)
(计算).当你的吸气剂不仅仅是吸气剂并且需要做一些逻辑时,一切都仍然是一致的.最后,这是IMO最大的问题:这很神奇.魔术非常非常糟糕,因为你必须知道魔法是如何正常使用它的.这是我在团队中遇到的一个问题:每个人都必须了解魔法,而不仅仅是你.
写作者和写作者都很难写(我讨厌他们),但他们是值得的.
vbe*_*nce 113
如果对象确实是"神奇的",你只需要使用魔法.如果你有一个具有固定属性的经典对象,那么使用setter和getter,它们工作正常.
如果您的对象具有动态属性,例如它是数据库抽象层的一部分,并且其参数在运行时设置,那么您确实需要魔术方法以方便使用.
use*_*291 85
我__get
尽可能地使用(和公共属性),因为它们使代码更具可读性.相比:
这段代码明确地说出了我在做什么:
echo $user->name;
Run Code Online (Sandbox Code Playgroud)
这段代码让我感到愚蠢,我不喜欢:
function getName() { return $this->_name; }
....
echo $user->getName();
Run Code Online (Sandbox Code Playgroud)
当您一次访问多个属性时,两者之间的差异尤为明显.
echo "
Dear $user->firstName $user->lastName!
Your purchase:
$product->name $product->count x $product->price
"
Run Code Online (Sandbox Code Playgroud)
和
echo "
Dear " . $user->getFirstName() . " " . $user->getLastName() . "
Your purchase:
" . $product->getName() . " " . $product->getCount() . " x " . $product->getPrice() . " ";
Run Code Online (Sandbox Code Playgroud)
是否$a->b
真的应该做的一件事或只是返回值是被调用者的责任.对于来电,$user->name
并且$user->accountBalance
应该看起来是一样的,尽管后者可能涉及复杂的计算.在我的数据类中,我使用以下小方法:
function __get($p) {
$m = "get_$p";
if(method_exists($this, $m)) return $this->$m();
user_error("undefined property $p");
}
Run Code Online (Sandbox Code Playgroud)
当有人调用$obj->xxx
并且类已get_xxx
定义时,将隐式调用此方法.因此,您可以根据需要定义一个getter,同时保持界面的统一和透明.作为额外奖励,这提供了记忆计算的优雅方式:
function get_accountBalance() {
$result = <...complex stuff...>
// since we cache the result in a public property, the getter will be called only once
$this->accountBalance = $result;
}
....
echo $user->accountBalance; // calculate the value
....
echo $user->accountBalance; // use the cached value
Run Code Online (Sandbox Code Playgroud)
底线:php是一种动态脚本语言,以这种方式使用它,不要假装你在做Java或C#.
归档时间: |
|
查看次数: |
114020 次 |
最近记录: |