我一直在阅读SPL中关于PHP的常用接口,比如Iterator、Countable和ArrayAccess。然而,我并不确切地理解它们是如何工作的。
他们的实现是否修改了PHP的核心功能,例如重载[]数组运算符?
我还读到了运算符扩展,它提供了以与低级语言相同的方式重载其他运算符的能力。由于运算符扩展明显修改了PHP核心,我想知道ArrayAccess是否在幕后以同样的方式工作?
我是一个修修补补的人,因此我发现在不知道引擎盖下面是什么的情况下很难使用某些东西。
发布于 2011-01-02 07:12:31
PHP和PHP扩展构建在Zend引擎之上。它们将Zend引擎功能公开给用户域(PHP脚本),并添加自己的特性,这些特性既可以公开给用户域,也可以公开给其他PHP扩展。
Zend引擎提供了一个对象模型,提供了访问对象维度的方法(ArrayAccess公开的功能)和用于遍历对象的通用迭代机制(Iterator的idem)。该对象模型由许多处理程序组成,PHP和任何扩展都可以替换为某种类型的对象( zend object handlers)。通过它的对象模型,Zend引擎实现了一种标准类型的对象( "zend对象“);每个对象都遵循zend_object数据结构,并且每个类--这是一个低级对象接口除了提供一种检索方法之外不知道的概念--通过zend_class_entry结构实现)。
ArrayAccess实际上不是一个SPL接口;它是在Zend引擎本身中定义的。zend对象的read_dimension/write_dimension/has_dimension低级处理程序的实现方式是,它们检查对象是否实现了这样的接口,如果实现了,则调用相应的方法(参见here)。
Iterator也不是SPL接口;它也是在Zend引擎中定义的。在这种情况下,对此接口的支持是在稍微高一点的级别上完成的。低级对象处理程序对对象迭代一无所知;这是Zend对象的一个特性。zend_class_entry结构在这里有两个相关的成员:iterator_funcs字段和get_iterator字段。这些定义了迭代器的操作和状态,以及如何创建新的迭代器。特别是对于Iterator,当类注册到运行时时,将检查它是否实现了该接口,如果实现了,则将该类的zend_class_entry变量中的相关字段设置为本机方法,从而将本机迭代接口连接到PHP方法。如果编写PHP扩展,可以选择编写本机迭代器(它在本地实现迭代方法),或者像在用户领域一样,实现Iterator并为几个操作编写PHP方法(在本例中是原生PHP方法),就像接口所描述的那样。
Countable接口是惟一一个真正是SPL接口的接口;Zend引擎对此一无所知。它的功能源于这样一个事实:count function的实现检查它是否存在,如果接口存在,则调用count方法。
操作员扩展在更低级别的设置下运行。在运行时,in直接写入Zend引擎的内存,并替换PHP代码编译成的操作码的处理程序(例如,现在ZEND_ASSIGN_ADD有了一个新的本机实现,它遵循用户可以选择的一些PHP函数/方法)。
https://stackoverflow.com/questions/4574703
复制相似问题