科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件PHP 5.0 中的对象重载技术研究

PHP 5.0 中的对象重载技术研究

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

PHP 5.0中引入了对象重载技术。本文将探讨对于方法__call(),__set()以及__get()进行重载的可能性。

作者:朱先忠编译 来源:天极网 2007年10月21日

关键字: Linux

  • 评论
  • 分享微博
  • 分享邮件
四、方法重载举例

  1. 动态的Getter/Setter方法

  下列代码实现了"动态"getter/setter方法以借助于方法重载的帮助来控制类。下面我们结合源代码进行分析:

<?php
 class DynamicGetterSetter {
  private $name = "Martin Jansen";
  private $starbucksdrink = "Caramel Cappuccino Swirl";
  function __call($method, $arguments) {
   $prefix = strtolower(substr($method, 0, 3));
   $property = strtolower(substr($method, 3));
   if (empty($prefix) || empty($property)) {
    return;
   }
   if ($prefix == "get" && isset($this->$property)) {
    return $this->$property;
   }
   if ($prefix == "set") {
    $this->$property = $arguments[0];
   }
  }
 }
 $class = new DynamicGetterSetter;
 echo "Name: " . $class->getName() . "\n";
 echo "Favourite Starbucks flavour: " . $class->getStarbucksDrink() . "\n\n";
 $class->setName("John Doe");
 $class->setStarbucksDrink("Classic Coffee");
 echo "Name: " . $class->getName() . "\n";
 echo "Favourite Starbucks flavour: " . $class->getStarbucksDrink() . "\n\n";
?>

  很明显,这里的两个属性$name和$starbucksdrink都是私有的,就是说从类的外部是不能够存取这些属性的。在面向对象的编程中,实现公共的getter/setter方法来存取或修改非公共属性的值是很经常的事情。实现这些是单调的事情,且相当耗费时间和精力。

  借助于方法重载可以容易得解决这个问题。不是为每个属性实现getter/setter方法,上面只实现了一个通用的__call()方法。这意味着当调用一个未定义的getter/setter方法如setName()或者getStarbucksdrink()时,PHP不会产生一个致命错误而流产,而是执行(或者代理到)魔术般的__call()方法。

  这是些简单介绍,下面我们对__call()作一下深入分析。

  2. 详细分析__call()方法

  __call()的第一个参数是原始的且尚未确定的方法(如setName),第二个参数是一个数字索引的一维数组,它包含了原始方法的所有参数。用两个参数("Martin"和42)调用一个未定义的方法将产生下面数组:

$class->thisMethodDoesNotExist("Martin", 42);
/导向__call()的第二个参数
Array
(
[0] => Martin
[1] => 42
)

  在方法__call()内部,如果原始方法以get或者set开头,则要进行某种计算以确定是否代码调用的是一个getter/setter方法。而且,这种方法还要进一步分析方法名的另外一组成部分(除去开始的三个字符),因为后面这部分字符串正代表getter/setter参照的属性的名字。

  如果方法名中指示有一个getter/setter,那么该方法或者返回相应的属性值,或者设置原始方法的第一个参数的值。如果没有的话,它不做任何事情,继续执行程序,好象没有事情发生。

  3. 实现目标

  实质上,相应于任意的属性,存在一种方法允许代码动态地调用任意的getter/setter方法,这种算法是存在的。这在短期内开发一个程序原型的情况下是很方便的:不是花费大量时间来实现getters/setters,开发人员可以专注于建模API并保证应用程序的根本正确。把__call()方法纳入到一个抽象类中甚至有可能使你在将来的PHP工程开发中实现代码的重用!

  4. 不足之外

  有优点就有缺点。以上方法也有几个不足:较大些的项目可以会使用象phpDocumentor这样的工具来跟踪API结构。用上面介绍的动态方法,所有的getter/setter方法当然不会出现在自动生成的文档中,这是无需多作解释的。

  另外一个不足是,类外面的代码可以存取类内的每一个私有属性。当使用真正的getter/setter方法时,有可能区别开外部代码可以存取的私有属性和对类外部不可见的"真正的"私有属性 - 因为我们有方法重载,而且有虚拟的getter和setter方法可以利用。

  五、结论

  本文通过两个例子细致分析了PHP 5.0中对象重载的两种情形。很希望本文的方法帮助你提高PHP编程的工作效率!同时,你也应清醒地看到这种方法的不足。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章