在某些对象上调用 count() 时重载 count() 的行为

2022-08-30 23:59:34

可能的重复:
使用 count() 对实现 ArrayAccess 的对象的元素进行计数?

在 PHP 5 中,你可以使用魔术方法,重载一些类,等等。在C++中,只要参数类型不同,就可以实现存在的函数。有没有办法在PHP中做到这一点?

我想做的一个例子是这样的:

class a {
    function a() {
        $this->list = array("1", "2");
    }
}

$blah = new a();

count($blah);

我想把2个回来。IE 对类中特定数组的值进行计数。因此,在C++中,我执行此操作的方式可能如下所示:

int count(a varName) { return count(varName->list); }

基本上,我正在尝试简化大型应用程序的数据调用,以便我可以调用以下命令:

count($object);

而不是

count($object->list);

该列表可能是一个对象列表,因此根据它的使用方式,如果有人必须以当前的方式执行此操作,则可能是非常令人讨厌的语句:

count($object->list[0]->list[0]->list);

那么,我可以做一些类似这样的东西:

function count(a $object) {
    count($object->list);
}

我知道PHP的计数接受混合变量,所以我不知道我是否可以覆盖单个类型。


答案 1

这听起来像是你想实现可数接口:

class a implements Countable {
    public function __construct() {
        $this->list = array("1", "2");
    }

    public function count() {
      return count($this->list);
    }
}

$blah = new a();

echo count($blah); // 2

答案 2

tl;dr - 答案位于底部:)

在PHP中,这个模型是相反的;而不是重载具有不同参数类型的函数(不是方法),每个类旨在为每个函数定义魔术方法。

下面是可以在类中定义魔术行为的函数列表。在示例中,对 的每个引用都是类的一个实例,引用缺少的属性并引用缺少的方法。$obj->unknown->blamethod()

  1. __toString() - 当您的对象在字符串上下文中使用时调用此方法,例如echo "My object is: $obj\n";

  2. __invoke([$arg 1..n]) - 当您的对象用作函数时,此方法被调用,例如$obj($a, $b);

  3. __get($prop) - 允许拦截访问类的不存在属性的尝试,例如;顺便说一句,这有时可以用作延迟加载某些属性的一种方式,否则在构造函数中完成时将花费大量处理。$obj->unknown

  4. __set($prop,$value) - 在设置不存在的属性时调用,例如$obj->unknown = 42;

  5. __isset($prop) - 被调用以确定不存在的属性的存在(我意识到这听起来有多有趣),例如 会打电话给isset($obj->unknown)$obj->__isset('unknown')

  6. __unset($prop) - 在此类情况下调用unset($obj->unknown);

  7. __call($name, $arguments) - 拦截对类中未实现方法的调用,例如 将调用$obj->blamethod(1, 2, 3);$obj->__call('blamethod', array(1, 2, 3));

  8. __callStatic($name,$arguments) - 喜欢,但您将无法在实现中使用。__call()$this

  9. __clone() - 在调用时调用,因此您可以决定保留哪些数据以及丢弃哪些数据。$x = clone $obj;

使用 SPL,通过实现某些接口引入了更多概念:

  1. 可遍历 - 一个抽象接口,它定义了在构造中使用时类的作用;具体接口称为迭代器foreach

  2. ArrayAccess - 一个允许使用类的实例作为数组使用的接口。

  3. 可序列化 - 定义两个要调用的方法的接口或 。它与使用 和 是互斥的。serialize()unserialize()__sleep()__wakeup()

  4. 可数 - 定义一个方法,每当在类实例上执行时调用。count()


推荐