在PHP中重载属性和方法 - 原因是什么?

Ale*_*lex 5 php overloading

仅仅因为可爱功能命名原因而使用重载是一个好主意吗?:)

例如:

echo $store->product->getPrice($currency);

  • product 将调用__get然后__getObject('product')执行magik的操作并返回当前正被视为对象的产品(如果是第一次调用则将其实例化)

echo $store->product('dog')->getPrice($currency);

  • 这里product将调用__call,然后调用__callObject('product',...)...


没有超载的替代方案是:

if(!$store->product)
  $store->product = new Product();

 echo $store->product->getPrice($currency);
Run Code Online (Sandbox Code Playgroud)

$product = new Product('dog');
echo $product->getPrice($currency);
Run Code Online (Sandbox Code Playgroud)

我真的很喜欢重载,因为我可以为我的课程获得很好的API.但缺点是重载的东西比直接调用属性/方法慢15倍.

可以像这样使用重载吗?

在我目前的应用程序中,我不会将重载成员调用超过1000次.这不应该对性能产生太大影响.也许额外0.1秒,考虑到一个站点通常在0.5 - 1s生成并不是那么多

hak*_*kre 3

仅出于可爱的函数命名原因而使用重载是个好主意吗?:)

不,我的意思是,这要看情况。:) 让我们为我们的编程生活增添一些精彩和可爱:

$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';
    }
}
Run Code Online (Sandbox Code Playgroud)

我必须承认,这个例子可能有点夸张,但它说明了一些事情。

首先,假设API是针对一个类的。所以它从一个非常普通的开始stdClass

然后这个例子展示的是这些神奇的函数可以用来重载装饰一些东西。可以,但一定不能。看看这个很棒的 AP​​I,它本身就很棒:

$awesome = new Awesome($ordinary);

echo $awesome->Caption, "\n"; # This caption is just awesome by itself!
# Hello
Run Code Online (Sandbox Code Playgroud)

然后看更可爱的 API 示例:

$lovely = new Lovely($ordinary);

echo $lovely->Caption, "\n"; # This caption is lovely, hughs and kisses everyone!
# <3 Hello <3
Run Code Online (Sandbox Code Playgroud)

所以在这个例子中,这是一个好主意,Lovely但对于 来说没有用Awesome,因为Awesome实际上更容易获得:

$awesome = $ordinary;
Run Code Online (Sandbox Code Playgroud)

这让我想到了一点,API 中的重载只能在特定的点上有用。如图Lovely所示,它可以用来装饰另一个(没有太多指定的对象),但它也表明这只是一次性的:Lovely已经需要知道如何Awesome通过使用(现在不魔法任何更长)__get方法:

    public function __get($name)
    {
        return '<3 ' . parent::__get($name) . ' <3';
    }
Run Code Online (Sandbox Code Playgroud)

当您现在考虑这Awesome是您的 API 时,您可以看到它阻止了其他想要使用它的编码人员轻松重载。

因此,在具体代码中重载是没问题的,API 不应该阻止这种情况。但当 API 本身超载时,事情就会变得很困难。

不仅对于编码来说,添加动态/魔法也会使调试变得困难。因此,最好对您创建的 API 保持清晰,并提供比[]或更具体的接口->。你可以给事物指定具体的名称,这样效果很好;)

然后它更可爱:

echo $store->getObject('product')->getPrice($currency);
Run Code Online (Sandbox Code Playgroud)