当前位置:Linux教程 - Linux - Zend Engine2.0版本设计蓝图概览

Zend Engine2.0版本设计蓝图概览



        
    Zend Engine

    2.0版本



    设计蓝图概览
    概览
    修补后使用对象句柄的对象模型
    背景
    需求
    概述
    功能实现实现
    兼容性说明
    依赖性说明
    与新的对象模型相关的改动
    函数中改进的对象返回机制
    背景
    需求
    概述
    功能实现实现
    兼容性说明
    依赖性说明
    改进的对象分离引用支持
    概述
    背景
    需求
    概述
    功能实现实现
    兼容性说明
    依赖性说明
    对象克隆
    背景
    需求
    概述
    功能实现
    兼容性说明
    依赖性说明
    析构器
    背景
    需求
    概述
    功能实现
    兼容性说明
    依赖性说明
    删除声明
    背景
    需求
    概述
    功能实现
    兼容性说明
    依赖性说明
    统一构建器
    背景
    需求
    概述
    功能实现
    兼容性说明
    依赖性说明
    其他附加特性
    多重继承
    背景
    需求
    概述
    功能实现
    兼容性说明
    依赖性说明
    私有成员变量
    背景
    需求
    概述
    功能实现
    兼容性说明
    依赖性说明
    静态成员变量
    背景
    需求
    概述
    功能实现
    兼容性说明
    依赖性说明
    违例处理(try/throw/catch)
    背景
    需求
    概述
    功能实现
    兼容性说明
    依赖性说明
    改进的面向对象语法中的过载
    背景
    需求
    概述
    功能实现
    兼容性说明
    依赖性说明
    字符串偏移量语法
    背景
    需求
    概述
    功能实现
    兼容性说明
    依赖性说明
    概览

    1.0版本的Zend Engine是PHP 4.0的核心。它为函数模块提供了底层架构支持和服务,同时实现PHP的语法。实际上Zend Engine 1.0是PHP脚本引擎的第二个修订版本;它还是最大程度上基于与PHP 3.0语法引擎(基本上就是所谓的Zend Engine 0.5)同样的分析规则。虽然显而易见这样的设计可以提供非常方便的途径供PHP 3.0升级到4.0,但是同时也将PHP语言在语法层次上(language-level)的改进限制在与PHP 3.0相似的思路中。
    由于PHP 3.0和4.0的空前成功,我们收到了来自开发者的大量反馈,其中指出了PHP语言中缺少的或是需要改进的各种特性。因此我们认为现在非常适合开始着手于撰写Zend Engine的下一个版本,其中将包含一些新的语言特性、改进现存的特性,同时针对开发者遇到的开发难题给出合适的解决方案。本文档的目的就是介绍Zend Engine 2.0的设计动机并对其基础特性进行深入描述。
    需要指出的是本文档中所述的Zend Engine 2.0的特性范围将在合理的时间表中实现。不过下一版本正式释出的Zend Engine也许会包含更多的特性。
    本文档在Zend Engine 2.0的最终版本释出之前仍可能会有更改。您可以在其邮件列表(向[email protected]订阅)中进行Zend Engine 2.0的讨论。
    修补后使用对象句柄的对象模型

    背景
    在Zend Engine 1.0(以及其前辈PHP 3.0语法引擎)中,对象模型的设计采用按值传递实例对象的方式。也就是说当开发者在进行诸如为函数进行变量分配和传递参数等操作时,对象的处理方式与其他主类型比如整型和字符型的处理方式相同。从语法上来说这意味着整个对象被拷贝。但是Java的对象操作方式则与此不同,它是按照对象句柄传递而非按值传递(您可以将对象句柄想象成对象的ID)。

    需求
    不行的是上述的对象处理方式已经严重束缚了Zend Engine的面向对象模型。其中一个关于此处理方式的难题就是对象实例化和复制的控制非常困难——这个问题不仅仅将导致低效率的开发,同时会经常出现运行时的行为异常。将现有对象模型改变成对象句柄模型有助于解决对象使用中的许多需要,比如析构器、废弃方法返回值、对于对象复制的紧密控制以及其他。

    概述
    设想中的对象模型将受Java模型的很大影响。一般说来,当您生成一个新的对象时您得到的是对象的句柄而非对象本身。当该句柄被传递至函数、被赋值以及被拷贝时,也仅仅是该对象的句柄被拷贝、传递、赋值。对象本身并不会被拷贝或复制。这将使得同一对象的众多句柄一直指向该同一对象,由此得到一致的解决方案并且节省了无谓的复制,省却了令人迷惑的行为。

    功能实现
    在对象模型转变之后对象的基本使用方法和现有语法引擎中的方法相比几乎没有改变。不过您再也不会步入危险的对象泥沼而迷惑于对象的拷贝和废弃了。
    您可以按照以下的代码生成并使用一个新的对象实例:

    $object = new MyClass();
    $object->method();

    以上代码将为$object赋值为类MyClass的一个对象实例的句柄并调用其类方法。
    再来考虑以下的代码:

    1 class MyClass
    2 {
    3 function setMember($value)
    4 {
    5 $this->member = $value;
    6 }
    7
    8 function getMember()
    9 {
    10 return $this->member;
    11 }
    12 }
    13
    14 function foo($obj)
    15 {
    16 $obj->setMember(“foo”);
    17 }
    18
    19 $object = new MyClass();
    20 $object->setMember(“bar”);
    21 foo($object);
    22 print $object->getMember();

    在不使用新的类似Java的对象处理方式时,第20行中对象的成员变量member被赋值为字符串值”bar”。根据Zend Engine 1.0中的对象内在表示方法,对象被标示成一个引用,但是当其被传递至函数foo(),该对象被复制(!)。因此第21行中调用函数foo仅仅意味着对$object对象的复制品调用setMember(“foo”)而非$object本身。因此第22行输出的结果是”bar”。
    以上的描述就是直至今日PHP语法引擎的运作方式。许多开发者可能没有意识到一个事实即他们通常是对对象的复制品进行操作而不是对象本身;另一些开发者也许已经发现可以指定传递对象的引用至函数来解决这个问题(除非在实际处理时确实需要对象的复制品,不过这种情况非常少见)。
    新的对象模型则会提供非常理想的如开发者初衷的支持。在第21行对象句柄被传递至函数foo()。在函数foo()内部,可以由对象句柄找到对象本身并对其进行setMember()方法调用而不是对其复制品进行操作。由此第22行应该输出”foo”。该方式为开发者提供了在对象产生和复制时更紧密的控制。另外一个相对不甚重要的益处是对象句柄将按值传递给函数foo(),尽最大可能的避免了多余的复制从而额外的优化了运行时性能。
    这只是关于新的对象模型为何能够消除原有不良的语言行为并使得对象操作更容易、更有效、更符合初衷的原因的简单描述。这种方式的改进所带来的重要性大大超越了本节所述的内容,您可以从以后的章节中获得更多基于此变化带来的新特性描述。

    兼容性说明
    因为许多开发者并没有意识到现有对象模型的“复制怪癖”,因此相对来说现在正好可以将一些以前运行缓慢甚至溢出的PHP应用工程直接或者稍加修改就可以在现有模型中非常流畅的运行。
    处于简单升级的目的,Zend Engine 2.0支持可选的“自动克隆”特性,即无论在1.0版本中的对象是否本应该被拷贝都会在新的对象模型中被克隆。同样可选的是,还可以要求语法引擎无论如何在以上所述的自动克隆产生时发出E_NOTICE级别的信息以便开发者逐步的升级到2.0版本风格的语法行为(无自动克隆特性)。

    依赖性说明
    新的对象模型并不依赖于其他特性。然而许多其他的Zend Engine 2.0新特性,比如类似$foo->bar()->barbara()的语法,析构器以及其他完全基于此对象模型。

    与新的对象模型相关的改动


    函数中改进的对象返回机制

    背景
    由于底层支持的不足,在Zend Engine 1.0中使得函数返回对象非常麻烦。如果需要函数bar()返回对象的引用,就需要使用如$foo = &bar()这样的特殊表示。另外,由于旧有对象模型所表现出的对象拷贝语义特性,采用将现有对象的引用赋值给一个按对象引用传递的函数参数并希望获得返回的对象引用也是不可能的。

    需求
    面向对象设计模式,比如工厂模式(Factory)(由一个核心函数生成对象)等等,已经越来越被普遍应用。支持这样的模式需要一个整洁的、一致的面向对象接口,以及能够使得对象间简单互联的能力。因此为这些模式提供支持的由函数返回对象引用的简单直接的语法就变得至关重要了。

    概述
    作为副作用之一,新的采用句柄的对象模型使得对象行为得以简化和改进。以上所述的通过在函数中通过return表达式或者采用按对象引用传递的函数参数的方法获得对象的引用都是可行的,而且并不需要多余的考虑。

    功能实现
    在函数中返回对象就像返回其他主类型(比如整型和字符型)的处理方式一样。被返回的对象一直指向被用户实例化的那个对象,而绝对不会在后台暗自进行拷贝的工作。
    考虑以下的代码:

    1 function FactoryMethod($class_type)
    2 {
    3 switch ($class_type) {
    4 case “foo”:
    5 $obj = new MyFoo();
    6 break;
    7 case “bar”:
    8 $obj = new MyBar();
    9 break;
    10 }
    11
    12 return $obj;
    13 }
    14
    15 $object = FactoryMethod(“foo”);

    在新的对象模型下这段代码会返回对象本身;它会生成类MyFoo的一个实例并向运行着的语法引擎返回此实例而不是该对象实例的拷贝。这与在Zend Engine 1.0下执行的行为是不同的,在后者下将返回对象的复制品而不是对象本身。
    另一个容易迷惑但重要的方面在于类MyFoo通过某种途径生成额外的对于自身的引用。在新的模型下对象仍会被正确的返回。但是在旧有对象模型下,当返回$obj时它将部分被复制,同时对其自身的引用会被代之以某些“幽灵”对象而不被返回。这个令人迷惑的行为是许多难以驱除的臭虫的源头。
    现有对该问题的解决办法是如function &FactoryMethod($class_type)一样定义一个函数并将第15行改为$object = &FactoryMethod(“foo”);。不过这个办法非常麻烦,并且代码非常接近错误。

    采用同样的例子,如果对象不是通过函数中的return返回而是通过函数参数的方式返回,那么您一样会困扰于同样的问题。考虑以下的函数原型:
    function FactoryMethod($object_type, &$resulting_object)

    当试图将生成的对象赋值给$resulting_object时,因为上面提到的原因依旧会出现行为异常。如果采用新的模型您就可以轻松的将对象句柄赋值给$resulting_object并可以在该函数外部使用这个对象。

    兼容性说明
    这部分关于对象模型改进的内容几乎不可能产生兼容性问题除非开发者依赖于运行时出现的超乎想象的对象拷贝。不过,这种改进“也许”会使得function &func()以及=&这样的语法显得无用,至少可以考虑将它们剔除。如果将它们剔除,可以考虑设立一个小小的转换器找到它们并提出警告(同时有可能替换旧的语法),并且这样做也没有任何困难。

    依赖性说明
    该特性依赖于Zend Engine 2.0新的对象模型。
    改进的对象分离引用支持

    概述
    支持方法返回对象的分离引用,比如$object->method()->method()(该特性也可能包括由函数返回对象的分离引用,比如$func()->method()->method())。(该特性同样可以包括一些更加复杂的语法比如$object->method()->member->method(),这表示某个类方法的返回值的一个成员变量也是一个对象,再调用该对象的某一个方法。)

    背景
    旧有对象模型不可能支持分离引用返回的对象。由于技术上的不可行性而不支持此特性。

    需求
    许多PHP开发者希望可以支持返回对象的分离引用。不仅仅是因为有助于更好的代码风格,而且在于可以防止特定的编程错误。
    在旧有对象模型下,$object->method()->method()->method()等价于以下代码:
    $tmp =& $object->method();
    $tmp =& $tmp->method();
    $tmp->method();

    同时,当于Java或者COM对象交互时,这样的语法更加自然一些。

    概述
    由于新的对象模型以及改进的语法分析器,由函数返回对象的句柄直接调用方法成为了现实。新模型的实质就是采用对象句柄,因此方法是由对象本身调用,而不是从同一对象的不同复制品中调用。

    功能实现
    根据该特性可以非常容易的如以下所示书写代码:
    $object->method()->method()->member = 5;

    因为该表达式中的中间结果都是返回的对象句柄而非对象本身,所以只要这些被调用的方法正确就可以完成对相应对象的正确操作。

    兼容性说明
    由于这样的语法在旧有Zend Engine中并不存在,因此不存在兼容性冲突。

    依赖性说明
    该特性依赖于Zend Engine 2.0新的对象模型。
    对象克隆

    背景
    直至今日开发者仍然没有办法决定对象在被复制时到底哪一个复本的构建器被运行。现有版本的Zend Engine对于对象复制采用“按位”复制的办法以保证对象的所有属性保持一致。

    需求
    生成一个含有原来对象所有属性的新对象复制品并不是一个常见的需求。一个很好的例子是如果您有一个表示GTK窗口系统的类并且该类包含了关于这个窗口的资源,那么如果您想得到一个该类的复制品就表示您想构建一个新的窗口包含有与前者同样的属性,并且掌握着与前者一样的关于窗口的资源。
    另一个例子是如果您使用的某一个类含有对另一个类的引用,当您复制父类的时候您同样希望复制被引用的对象使得新的父类复制品也可以拥有自己的对另外那个类的引用关系。

    概述
    当开发者试图进行对象克隆时,Zend Engine首先搜寻该类中是否存在名为__clone()的方法。如果该方法不存在,则语法引擎调用默认的__clone()方法将该对象的所有属性进行复制。如果该方法存在,那么语法引擎将采用这个用户定义的方法负责新的对象复制品中所需属性的设定。方便起见,语法引擎自动支持将所有属性从源对象中按值引入新对象,也就是说在用户定义的__clone()方法中只需要对一些需要进行修改的属性进行重载。

    功能实现
    克隆一个对象的推荐语法如下:
    $copy_of_object = $object->__clone();

    兼容性说明
    如果在旧有代码中存在某个类包含有名为__clone()的方法,那么可能该方法不会如开发者所愿的被正确调用。不过很容易从旧有代码中检出并修改这个问题。

    依赖性说明
    该特性在新的对象模型中引人注目,虽然在旧有模型中同样也可以实现该特性。
    析构器

    背景
    目前并不存在类的析构机制,虽然PHP已经可以支持指定在发生停止请求时被调用的函数。

    需求
    具有定义对象析构器的能力非常有用。析构器可以记录调试信息、清除临时文件以及进行其他工作。

    概述
    设想中的析构器将与大部分面向对象语言中的情况相似。当最后一个关于某对象的引用被清除之后、该对象被清理出内存之前,该对象的析构器被调用。不过由于PHP的执行特点该特性尚待严密评估。举例说来,当执行时发生致命错误时对象的析构器就有可能不被调用,或者对象处于一个引用环中由此引用计算机制无法探测出对象的废弃时析构器也不可能被调用。

    功能实现
    开发者需要在类中定义一个名为__destruct()的方法(该方法不接受任何参数)。
    因此可能会如以下所示:
    class MyClass
    {
    function __destruct()
    {
    … // Run destructor code
    }
    }

    与构建器类似,父类的析构器不会被语法引擎默认调用。如果需要调用父类的析构器,需要在析构器函数体中显式的调用parent::__destruct()。

    兼容性说明
    由于该特性在旧有语法引擎中并不存在,因此没有兼容性问题。

    依赖性说明
    该特性依赖于新的对象模型。
    删除声明

    背景
    在旧有对象模型中如果仍有对某对象的引用,则没有办法强制删除该对象。

    需求
    在(某些设计模式中)有核心对象存在的情况下我们认为开发者在特定条件下需要强制对象在程序执行的特定位置被销毁。也许可以很简单的用$obj = NULL来完成,但是如果还有其他变量仍持有该对象的引用,那么这个语句就不能在期望的时候删除该对象。因此Zend Engine需要有在对象仍被引用的情况下强制被销毁的办法。

    概述
    设想中的delete声明将针对这个问题。它将在调用对象的析构器之后销毁该对象,即使此时该对象仍在其他地方被引用。这些对于已被删除对象的引用将失效,试图使用该对象将会导致致命错误。

    功能实现
    如前面概述中所述,delete声明将强制对象的销毁。
    语法规则如下:
    delete $object;

    兼容性说明
    由于该特性在旧有语法引擎中并不存在,因此没有兼容性问题。

    依赖性说明
    该特性依赖于新的对象模型。

    统一构建器

    背景
    Zend Engine允许开发者为自定义的类声明构建器。含有构建器的类在每个新的对象被生成时调用该构建器,因此将对象可供使用之前需要进行的初始化工作放入构建器中非常合适。在Zend Engine 1.0中,构建器作为普通的类方法被命名为与类名称同名。如果在一个类中含有与类名称同名的方法——那么该方法被自动视为构建器。

    需求
    由衍生类中调用父类的构建器是十分普遍的情况,但是在Zend Engine 1.0中当类存在于一个庞大的继承体系中时会带来一些麻烦。如果一个类的父类被改变,那么该类的父类的构建器名称也会随之改变,因而该类中调用父类构建器的代码也需要改变。

    概述
    Zend Engine 2.0将会引入一种声明构建器的标准办法——简单的调用名为__construct()的方法。

    功能实现
    例如:
    class Shape {
    function __construct()
    {
    // shape initialization code

    }

    };

    class Square extends Shape {
    function __construct()
    {
    parent::__construct();
    // square-specific initialization code

    }

    };

    如果我们决定引入另一个新的Rectangle类进行Shape和Square的继承关系:
    class Rectangle extends Shape {
    function __construct()
    {
    parent::__construct();
    // rectangle initialization code
    }

    };

    我们不需要修改Square类中的任何代码,需要做的仅仅是改变其父类:
    class Square extends Rectangle {

    };


    兼容性说明
    处于向后兼容的考虑,如果语法引擎没有找到指定类中名为__construct()的方法,它还将继续寻找以类名称命名的旧有风格的构建器。也就是说唯一会造成兼容性问题的情况是类中含有执行其他非构建器操作的名为__construct()的方法。

    依赖性说明
    无依赖性。

    其他附加特性


    多重继承

    注意:多重继承的支持也许会或者也许不会成为Zend Engine 2.0的一部分。是否将其加入语法引擎将被公开讨论。

    背景
    在Zend Engine 1.0中子类只能从单一的父类中继承接口和功能。

    需求
    有时需要定义含有多个类中的功能的新类。如果多重继承可行则可以实现该操作。

    概述
    Zend Engine 2.0将允许子类从多于一个的父类中继承。子类将具有其每个父类定义的所有方法,以及自身定义的所有方法。在单一继承中子类可以对父类中的方法进行重载。而在两个父类含有相同的方法名称的情况下,子类必须重载该方法(如果可能,Zend Engine还将探测是否该两个方法为非常相似的方法(在“菱形”继承的情况下)),由此自动的避免冲突。

    功能实现
    支持类继承多个父类的代码例示如下:
    class child extends parent1, parent2, … {

    };


    兼容性说明
    一些特定的函数比如get_parent_class()将被改写(例如该函数应该根据实际情况任意返回多个父类的列表或者单个父类)。另外,多重继承向下兼容单一继承,因此不会引入额外的兼容性问题。

    依赖性说明
    为实现基于多重继承的健全的类继承体系,有必要使用私有成员变量。从这方面意义说来,该特性依赖于私有成员变量特性。

    私有成员变量

    注意:私有成员变量的支持也许会或者也许不会成为Zend Engine 2.0的一部分。是否将其加入语法引擎将被公开讨论。

    背景
    在Zend Engine 1.0中类中的所有变量都可在类外部存取读写。

    需求
    通常为了保持对象的坚固性和保护数据,对象应该包含有只能由所属类中的方法存取的信息。另外,在被引入Zend Engine 2.0的新特性多重继承中,防止某一父类中的成员变量仅仅因为同名就与另一父类的成员变量发生冲突的情况出现显得尤其重要。

    概述
    Zend Engine 2.0将引入新的语法以声明成员变量为私有。私有成员变量只能被所属类中的方法所存取。如果在类方法的有效范围之外的试图访问私有成员变量,将会导致致命错误。根据设想中的实现,不允许间接的引用私有成员变量(比如使用$$varname的方式),只允许以指定变量名的方式直接使用。

    功能实现
    私有成员变量可以被如下所示的声明和使用:
    class foo {
    private $priv_var;
    function some_method(…)
    {
    $priv_var = …;
    }
    };
    $obj = new foo;
    $obj->priv_var = …; // will result in a fatal error


    兼容性说明
    没有兼容性说明。

    依赖性说明
    无依赖性。
    静态成员变量

    背景
    Zend Engine 1.0引入了通过类名称调用类方法的能力,从而可以无需使用类的实例(比如class_name::method())。不过,语法引擎并没有提供相似的方法访问类变量。事实上,Zend Engine 1.0中的类并没有存储类变量的能力。

    需求
    对于存储特定类中的信息的需求已经越来越普遍。在1.0版本中除了在类中使用全局变量的方法之外,没有其他办法可以实现,并且为了与其他全局变量的冲突,类中定义的全局变量的命名通常需要带有合适的前缀。

    概述
    2.0版本将引入类局部变量——属于特定类的变量。访问这些变量的语法与通过类名称调用类方法的语法相似。

    功能实现
    以下例示为实现一个单一类:
    class Logger {
    static $m_Instance = NULL;
    function Instance()
    {
    if (Logger::$m_Instance == NULL) {
    Logger::$m_Instance = new Logger();
    }
    return Logger::$m_Instance;
    }
    function Log()
    {

    }
    };
    $Logger = Logger::Instance();
    $Logger->Log(…);


    兼容性说明
    无兼容性问题。

    依赖性说明
    无依赖性。
    违例处理(try/throw/catch)

    背景
    至今尚无违例处理机制。虽然一些特定的错误可以被产生并被注册过的错误处理器处理,但是那些并不是语法层次(language-level)上的结构化的违例处理。

    需求
    违例处理在应用恰当时是非常优秀的工具(它应该被用来捕获错误而不是控制常规的程序流程)。对于开发者来说,能够以try/catch的结构来保护大块代码而无需在可能出错的每一行中提防错误的产生的方式非常有用。这样处理通常都很有意义,原因在于当不是所有的代码都执行无误时您需要找出错误信息,这时采用这样的结构可以避免在可能产生错误的每一行中书写错误处理的代码。

    概述
    设想中try/throw/catch的实现将与其他流行的编程语言类似。在try/catch块中的任何代码都可以向最近的违例处理器抛出违例。如果该违例处理器并不试图处理该违例,则它会继续抛出该违例。
    内部函数(通常以C写就)可以产生违例,不过它们更多可能的还是继续返回错误代码而非违例。大多数开发者也许不大需要使用违例,同时现有的内部函数的错误报告机制运作得也非常良好。

    功能实现
    以下是通常建议采用的语法:
    1 try {
    2 …code
    3 if (failure) {
    4 throw new MyException(“Failure”);
    5 }
    6 …code
    7 } catch ($exception) {
    8 … handle exception
    9
    10 throw $exception; // Re-throw exception.
    11 }

    try/catch块中的代码始于第2行,止于第6行。任何在这个代码块中产生的违例都将被catch语句处理(除非该代码块中还存在未写出的更加接近的try/catch块)。任何类型的值都可以作为违例被抛出,当该违例到达catch语句时就可以由开发者定义的$exception变量来访问(在第7行中的$exception也可以替换成其他任何合适的变量,比如$foobar)。
    当违例被抛出时是按值抛出的。被抛出的违例将越过所有的代码和函数堆栈直到最接近的catch语句。违例处理代码可以检查传来的违例变量$exception以便决定是自己处理还是继续向下一个违例处理器传递,然后根据自己的决定处理之。
    注意:该特性在特定情况下可能会造成内存漏洞。因此,开发者必须确信将该特性使用在不会出现过长生命周期的应用(比如web应用)中,而且只是进行结构化的违例处理而非流程控制。

    兼容性说明
    由于旧有版本语法引擎中不存在该特性,因此无兼容性问题。为在现有代码中简化错误处理,语法引擎将支持错误(比如E_WARING和E_NOTICE)产生违例而不显示错误的模式。这样的方式允许开发者在大段代码块之上使用try…catch结构从任何可能的错误中恢复(比如建立与数据库服务器的连接、选择一个数据库以及执行一个查询请求),而无需增加许多额外的错误处理代码。

    依赖性说明
    无依赖性。

    改进的面向对象语法中的过载

    背景
    PHP 4.0引入了面向对象语法的过载概念以方便操作外部对象或组件,比如COM组件或Java对象。该特性可以更加自然的使用面向对象的方式处理面向对象接口,而不是在PHP 3.0中唯一的选择——过程接口。

    不过,Zend Engine 1.0对该特性的支持(可以在PHP 4.0中表现出)受到了多方面的束缚,并且在编码上比较困难。
    限制和困难包括:
    1. 由于Zend Engine 1.0分析器的限制,2. 对于期望的行为有时不3. 可能写出相应的正确的代码。比如,4. $foo->bar->baz = 5; 该表达式在COM或者Java中都是有效的,而5. 在Zend Engine中则不6. 可行。
    7. 由于Zend Engine需要在执行时为每一过载表达式维护一棵完整的“解析树”,8. 过载机制的执行性能相对较低。
    9. 支持面向对象语法过载由于需要执行所有必要的操作而10. 必须遍历整个以上所述的解析树,11. 因此造成困难。
    12. 一个面向对象语法过载的模块需要对整个对象进行过载;过载对象的一部分而13. 将其他部分作为普通的Zend对象对待是不14. 可能的。

    需求
    以上的缺陷在PHP 4.0对Java支持的缺乏上表现得非常明显——不但收到限制而且难于调试。另一个例子是现在正迅速受到关注的PHP-GTK扩展;PHP-GTK极大的受制于以上所述的缺陷,尤其是第1条和第4条。

    概述
    Zend Engine 2.0将针对以上提到的所有问题推出面向对象语法过载的新接口。新的支持将放弃原有的在运行时维护一棵解析树并将其传递至模块进行再处理的方式;取而代之的是,Zend Engine将允许一些特定的细小操作(如访问、赋值以及方法调用)在各个阶段分别过载。该方式的好处在于:
     简化了面向对象语法过载模块的开发;
     允许被过载的对象既可以包含其他过载对象又可以包含标 准的Zend值类型(zval’s)。
    这样,在标准Zend读、写、方法调用时的相同阶段,对于过载操作也会产生引人注目的性能提升。

    功能实现
    新的面向对象语法过载模块将使得模块开发者以更自然的方式操作过载;也许更重要的是,根据Zend Engine 2.0计划中的语法改进,新的面向对象语法模块将允许其他对象模型比如COM或Java与Zend表达式之间的完全语法兼容。

    兼容性说明
    开发者不会遇到任何兼容性问题;新的API将既支持与旧有相似的功能,又支持一些新的功能(比如$foo->bar()->baz)。不过(对于我们来说)需要重写现有的面向对象语法过载支持模块以支持新的API。

    依赖性说明
    该特性依赖于Zend Engine 2.0新的对象模型。

    字符串偏移量语法

    背景
    有时需要访问一个字符串中的某一特定字符。Zend Engine 1.0中并没有针对字符串中偏移量引用的特殊表示办法。作为代替,字符串可以被分解为由单个字符组成的数组,使用数组偏移量的函数,就可以访问相应的字符。

    需求
    以下特别将字符串偏移量语法加入Zend Engine的三个主要原因:
    1. 旧有的对字符串和数组均可使用偏移量的语法含混不2. 清。对于这样的代码$str[0] = “a”; 其中$str为一个空字符串。(根据PHP 4以及PHP 3的行为)$str将被自动看作数组处理,3. 因此作为数组的$str其偏移量位置0的值为字符串”a”。然而,4. 一些开发者却希5. 望$str的最终结果是字符串”a”。
    6. 对于字符串偏移量引入专门的语法可以在编译时分清是针对字符串的偏移,7. 由此可以某种程度上优化运行时的效率。
    8. 从语义角度上说这种方式有利于在一个代码片断中甄别出开发者的操作对象是字符串偏移量还是数组偏移量。

    概述
    Zend Engine将为字符串偏移量引入新的语法。对字符串偏移使用数组偏移量语法将被不被提倡并会得到运行时警告(可能是E_NOTICE或者E_STRICT)。

    功能实现
    以下是推荐的使用语法:
    $str{2} = ‘a’;

    新功能的示例代码如下:
    $str1 = $str2 = “”;
    $str1{0} = ‘a’;
    $str2[0] = ‘a’;

    作为执行结果,$str1将为字符串”a”而$str2将为数组(0 => “a”)。

    兼容性说明
    为方便开发者升级其代码,对字符串偏移使用数组偏移量语法会得到警告。但是考虑到向后兼容,是否在对字符串偏移使用数组偏移量语法之时产生错误还值得考虑。

    依赖性说明
    无依赖性。
    发布人:yfy001 来自: