5

我一直在从 SPL 中阅读有关 PHP 常用接口的信息,例如IteratorCountableArrayAccess. 但是,我不完全了解它们是如何工作的。

他们的实现是否修改了 PHP 的核心功能,例如重载[]数组运算符?

我还阅读了有关运算符扩展的信息,它提供了以与低级语言相同的方式重载其他运算符的能力。由于 Operator 扩展明确修改了 PHP 核心,我想知道是否ArrayAccess在幕后以相同的方式进行操作?

我是一个修补匠,因此我发现在不知道引擎盖下的东西的情况下很难使用某些东西。

4

1 回答 1

11

PHP 和 PHP 扩展构建在 Zend 引擎之上。它们将 Zend 引擎功能暴露给用户空间(PHP 脚本)并添加自己的特性,这些特性要么暴露给用户空间,要么暴露给其他 PHP 扩展。

Zend 引擎提供了一个对象模型,可以访问对象维度(由 公开的功能ArrayAccess)和用于迭代对象的通用迭代机制(同上Iterator)。这个对象模型由许多处理程序组成,PHP 和任何扩展都可以替换为一种类型的对象(zend 对象处理程序)。Zend 引擎在其对象模型上实现了一种标准类型的对象(“zend 对象”);每个对象都遵循zend_object数据结构,每个类——这是一个低级对象接口除了提供一种检索它的方法之外不知道的概念——通过一个zend_class_entry结构)。

ArrayAccess实际上不是 SPL 接口;它是在 Zend 引擎本身中定义的。read_dimension// write_dimensionzend对象的has_dimension低级处理程序的实现方式是检查对象是否实现了这样的接口,如果是,则调用相应的方法(参见此处)。

Iterator也不是 SPL 接口;它也在 Zend 引擎中定义。在这种情况下,对这个接口的支持是在稍高的水平上完成的。低级对象处理程序对对象迭代一无所知;这是 Zend 对象的一个​​属性。该zend_class_entry结构在这里有两个相关成员:iterator_funcs字段和get_iterator字段。这些定义了迭代器的操作和状态以及如何创建一个新的迭代器。特别是,当一个类在Iterator运行时注册时,它会检查它是否实现了该接口,如果实现了,则检查该接口中的相关字段zend_class_entry该类的变量设置为将本机迭代接口连接到 PHP 方法的本机方法。如果要编写 PHP 扩展,可以选择通过编写本机迭代器(本机实现迭代方法)或像在用户空间中一样Iterator,为几个操作,就像界面描述的那样。

Countable接口是唯一一个实际上是 SPL 接口的接口;Zend 引擎对此一无所知。它的功能来源于这样一个事实,即count函数的实现检查它的存在并count在接口存在时调用方法。

操作员扩展在较低级别的设置下运行。在运行时,in 直接写入 Zend 引擎的内存并替换 PHP 代码编译成的操作码的处理程序(这样现在例如ZEND_ASSIGN_ADD有了新的本机实现,它遵循用户可以选择的一些 PHP 函数/方法)。

于 2011-01-01T23:12:31.353 回答