在PHP中重载属性和方法 - 原因是什么?
使用重载仅用于可爱的功能命名原因是一个好主意吗? :)在PHP中重载属性和方法 - 原因是什么?
例如:
echo $store->product->getPrice($currency);
-
product
将调用__get然后__getObject(“产品”)来完成玛姬东西,并返回该用户正在观看作为对象的当前产物(它是实例化,如果是第一次调用)
echo $store->product('dog')->getPrice($currency);
- 这里
product
将调用__call,然后__callObject( '产品',...)...
没有超载另一种方法是:
if(!$store->product)
$store->product = new Product();
echo $store->product->getPrice($currency);
和
$product = new Product('dog');
echo $product->getPrice($currency);
我真的很喜欢重载,因为我可以为我的课程获得很好的API。但缺点是重载的东西比直接调用属性/方法要慢15倍。
可以像这样使用重载吗?
在我当前的应用程序中,我没有调用超过1000次的超载成员。这应该不会对性能产生太大影响。也许额外0.1s,考虑到一个网站通常生成0.5 - 1s不是很多
的是它使用重载全权可爱的功能命名的原因是一个好主意? :)
不,我的意思是,这取决于。 :)让我们有些迷死和可爱添加到我们的编程生涯:
$ordinary = new stdClass();
$ordinary->Caption = 'Hello';
class Awesome
{
private $ordinary;
public function __construct($ordinary) {
$this->ordinary = (array) $ordinary;
}
public function __get($name) {
$value = '';
return $this->ordinary[$name];
}
}
class Lovely extends Awesome
{
public function __get($name)
{
return '<3 ' . parent::__get($name) . ' <3';
}
}
我必须承认,例如可能是一个比最高位,但显示了一些。
首先,假设API是针对一个类的。所以它从一个非常普通的stdClass
开始。
什么例子则说明的是,那些神奇的功能,可用于超载或装饰东西。可以,但不可以。见真棒API,它本身只是真棒:
$awesome = new Awesome($ordinary);
echo $awesome->Caption, "\n"; # This caption is just awesome by itself!
# Hello
然后看到更可爱的API例如:
$lovely = new Lovely($ordinary);
echo $lovely->Caption, "\n"; # This caption is lovely, hughs and kisses everyone!
# <3 Hello <3
因此,在这个例子中,它是Lovely
一个好主意,但它是无用的Awesome
,因为Awesome
实际上是更容易获得:
$awesome = $ordinary;
这使我想到了一点,即在API中重载可以ONL y在某个特定点上是有用的。正如Lovely
所示,它可以用来装饰另一个(没有多少指定的对象),但它也表明这只是一次性的:Lovely
已经需要知道如何调用Awesome
以利用它的功能(现在不是魔术再)__get
方法:
public function __get($name)
{
return '<3 ' . parent::__get($name) . ' <3';
}
当你现在考虑Awesome
是你的API,你可以看到,它阻止本身能够被从想要利用它的另一coderette容易过载。
因此,在具体的代码中,重载可以很好,API不应该阻止这种情况。但是,当API本身过载时,事情可能变得困难。
不仅对于编码,添加动态/魔法还会使事情难以调试。因此,请更好地保持您创建的API的清晰,并提供更具体的接口,然后只需[]
或->
。你可以给的东西具体名称和行之有效;)
而且它更可爱那么:
echo $store->getObject('product')->getPrice($currency);
重载的缺点是,你必须自己描述“漂亮的API”,因为文档工具不能理解,什么你在你的方法里面做。还有一点是,它通常“太过神奇”:你让你的代码更难以理解你实现的更多魔法。
另一方面,我没有看到您的替代方案有任何问题。它在我眼中更清洁。
旁注:只要你没有实现魔术方法,在你自己的方法开始时避免使用双下划线。
在这段代码的性能开销似乎并不显著。但我通常害怕使用大量的__call和__get方法(假设你将在整个软件中使用它) – TFennis 2012-01-03 12:13:31
如果你的整个API依赖于Magic Methods,那么性能影响可能很大,并且有一个很多人不喜欢魔法代码,因为它并不明显。 – Gordon 2012-01-03 12:18:36