简体   繁体   English

ArrayAccess如何工作?

[英]How does ArrayAccess work?

I've been reading about the commonly used interfaces of PHP from the SPL, such as Iterator , Countable , and ArrayAccess . 我一直在阅读有关SPL中常用的PHP接口,例如IteratorCountableArrayAccess However, I don't understand exactly how they work. 但是,我不确切地知道它们是如何工作的。

Do their implementations modify the core functionality of PHP, for example overloading the [] array operator? 他们的实现是否修改了PHP的核心功能,例如重载[]数组运算符?

I've read also about the Operator extension, which provides the ability to overload other operators in the same fashion as lower level languages. 我还读过有关Operator扩展的内容,它提供了以与低级语言相同的方式重载其他运算符的能力。 Since the Operator extension clearly modifies the PHP core, I was wondering if ArrayAccess acts in the same way behind the scenes? 由于Operator扩展明确地修改了PHP核心,我想知道ArrayAccess是否在幕后以相同的方式运行?

I'm a tinkerer, consequently I find it difficult to use something without knowing what's under the hood. 我是一个修补匠,因此我发现很难在不知道引擎盖的情况下使用它。

PHP and PHP extensions are built on top of the Zend Engine. PHP和PHP扩展构建在Zend引擎之上。 They expose the Zend Engine functionality to user-land (PHP scripts) and add features of their own, which are either exposed to user-land or to other PHP extensions. 它们将Zend Engine功能暴露给用户自定义(PHP脚本)并添加自己的功能,这些功能要么暴露给用户区域,要么暴露给其他PHP扩展。

The Zend Engine provides an object model with a way to access object dimensions (the functionality exposed by ArrayAccess ) and a general iteration mechanism that's used to iterate over objects (idem for Iterator ). Zend Engine为对象模型提供了访问对象维度( ArrayAccess公开的功能)的方法,以及用于迭代对象的迭代机制( Iterator idem)。 This object model consists of a number of handlers that PHP and any extension can replace for a type of object (the zend object handlers ). 该对象模型由许多处理程序组成,PHP和任何扩展可以替换一种对象( zend对象处理程序 )。 Over its object model, the Zend engine implements a standard type of objects (the "zend objects"); 在它的对象模型中,Zend引擎实现了一种标准类型的对象(“zend对象”); each object has follows the zend_object data structure, and each class -- which is a concept that the low-level object interface doesn't know apart from providing a way to retrieve it -- by a zend_class_entry structure). 每个对象都遵循zend_object数据结构,每个类 - 这是一个低级对象接口不知道的概念,除了提供检索它的方法 - 由zend_class_entry结构)。

ArrayAccess is actually not an SPL interface; ArrayAccess实际上不是SPL接口; it's defined in the Zend Engine itself. 它在Zend Engine本身中定义。 The read_dimension / write_dimension / has_dimension low-level handlers of zend objects are implemented in such a way that they check whether the object implements such interface and call the respective methods if that's the case (see here ). zend对象的read_dimension / write_dimension / has_dimension低级处理程序以这样的方式实现,即它们检查对象是否实现了这样的接口并调用相应的方法(如果是这种情况)(参见此处 )。

Iterator is also not an SPL interface; Iterator也不是SPL接口; it's also defined in the Zend Engine. 它也在Zend引擎中定义。 In this case, the support for this interface is done at a slightly higher level. 在这种情况下,对此接口的支持是在稍高的级别完成的。 The low-level object handlers know nothing of object iteration; 低级对象处理程序对对象迭代一无所知; this is a property of Zend Objects. 这是Zend Objects的一个属性。 The zend_class_entry structure has two relevant members here: the iterator_funcs field and the get_iterator field. zend_class_entry结构在这里有两个相关成员: iterator_funcs字段和get_iterator字段。 These define the iterator operations and state and how to create a new iterator. 这些定义了迭代器操作和状态以及如何创建新的迭代器。 For Iterator in particular, when a class is registered with the runtime, it's checked whether it implements that interface, and if it does, the relevant fields in the zend_class_entry variable for that class are set to native methods that bridge the native iteration interface to PHP methods. 特别是对于Iterator ,当一个类在运行时注册时,会检查它是否实现了该接口,如果是,则将该类的zend_class_entry变量中的相关字段设置为将本机迭代接口桥接到PHP的本机方法方法。 If one writes a PHP extension, one can opt by either writing a native iterator (which implements the iteration methods natively) or to, just like in user-land, implement Iterator and write PHP methods (in this case, native PHP methods) for the several operations, like the interface describes. 如果编写PHP扩展,可以选择编写本机迭代器(本机实现迭代方法),或者像在用户区中一样,实现Iterator并编写PHP方法(在本例中为本机PHP方法)几个操作,如界面描述。

The Countable interface is the only one that's actually an SPL interface; Countable接口是唯一一个实际上是SPL接口的接口; the Zend Engine knows nothing about it. Zend Engine对此一无所知。 Its functionality is derived from the fact that the implementation of the count function checks for its presence and calls the count method if the interface exists. 它的功能来自于count函数的实现检查其存在的事实,并且如果接口存在则调用count方法。

The operator extension operates at a more low-level setting. 操作员分机在更低级别的设置下运行。 At runtime, in directly writes into the memory of the Zend Engine and replaces the handlers of the opcodes PHP code compiles into (so that now eg the ZEND_ASSIGN_ADD has a new native implementation, which defers to some PHP function/method the user can choose). 在运行时,直接写入Zend Engine的内存并替换PHP代码编译的操作码的处理程序(现在例如ZEND_ASSIGN_ADD有一个新的本机实现,这ZEND_ASSIGN_ADD用户可以选择的某些PHP函数/方法) 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM