找回密码
 注册
【阿里云】2核2G云新老同享 99元/年,续费同价华为云精选云产品特惠做网站就用糖果主机Jtti,新加坡服务器,美国服务器,香港服务器
查看: 382|回复: 1

第十五节--Zend引擎的发展 -- Classes and Objects in PHP5 [15]

[复制链接]
发表于 2005 年 10 月 8 日 15:42:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

×
  第十五节--Zend引擎的发展本章的最后一节,Zeev讨论了Zend引擎带来的对象模型,特别提到它与PHP的前几个版本中的模型有什么
不同.当1997年夏天,我们开发出PHP3, 我们没有计划要使PHP具备面向对象的能力. 当时没有任何与类和对象有关的想法. PHP3是
一个纯粹面向过程的语言. 但是,在1997.8.27的晚上PHP3 alpha版中增加了对类的支持. 增加一个新特性给PHP,当时仅需要极少
的讨论,因为当时探索PHP的人太少. 于是从1997年八月起, PHP迈出了走向面向对象编程语言的第一步.确实,这只是第一步. 因为
在这个设计中只有极少的相关的想法,对于对象的支持不够强大. 这个版本中使用对象仅是访问数组的一个很酷的方法而已. 取代
使用$foo[“bar”],你可以使用看起来更漂亮的$foo->bar. 面向对象方法的主要的优势是通过成员函数或方法来储存功能. 例子
6.18中显示了一个典型的代码块. 但是它和例6.19中的做法其实并没有太大不同.Listing 6.18 PHP 3 object-oriented
programming PHP3中的面向对象编程value;        }    }    $obj = new Example();    $obj-&gtrintValue(); ?> Listing
6.19 PHP 3 structural programming PHP3 PHP3中的结构化编程 以上我们在类中写上两行代码,或者显示地传递数组给函数. 但
考虑到PHP3中这两种选择并没有任何不同,我们仍然可以仅把对象模型当成一种”语法上的粉饰”来访问数组. 想要用PHP来进行
面向对象开发的人们,特别是想使用设计模式的人,很快就发现他们碰壁了. 幸运地,当时(PHP3时代)没有太多人想用PHP来进行面
向对象开发.PHP4改变了这种情况. 新的版本带来了引用(reference)的概念, 它允许PHP的不同标识符指向内存中的同一个地址.
这意味着你可以使用两个或更多的名称来给同一个变量命名,就像例6.20那样.Listing 6.20 PHP 4 references PHP4中的引用 由
于构建一个指向彼此的对象网络是所有面向对象设计模式的基础,这个改进具有非常重大的意义.当引用允许建立更多强大的面向
对象应用程序, PHP对待对象和其它类型数据相同的做法带给开发者极大的痛苦.就像任何PHP4的程序员将会告诉你的, 应用程序
将会遭遇WTMA(Way Too Many Ampersands过多&)综合症. 如果你想构建一个实际应用,你会感到极为痛苦,看看例6.21你就明
白.Listing 6.21 Problems with objects in PHP 4 PHP4中使用对象的问题1    class MyFoo { 2        function MyFoo() 3        
{ 4            $this->me = &$this; 5            $this->value = 5; 6        } 7 8        function setValue($val) 9        
{ 10            $this->value = $val; 11        } 12 13        function getValue() 14        { 15           
return $this->value; 16        } 17 18        function getValueFromMe() 19        { 20            return $this->
me->value; 21        } 22    } 23 24        function CreateObject($class_type) 25        { 26            switch
($class_type) { 27                case foo: 28                    $obj = new MyFoo(); 29                    
break; 30                case bar: 31                    $obj = new MyBar(); 32                    break; 33           
} 34            return $obj; 35        } 36 37        $global_obj = CreateObject (foo); 38        $global_obj->
setValue(7); 39 40        print Value is  . $global_obj->getValue() . \n; 41        print Value is  .
$global_obj->getValueFromMe() . \n; 让我们一步步来讨论. 首先,有一个MyFoo类.在构造函数里,我们给$this->me一个引用,
并设定我们有其它三个成员函数: 一个设定this->value的值;一个返回this->value的值;另一个返回this->value->me的值. 但
是--$this不是相同的东西吗? MyFoo::getValue()和MyFoo::getValueFromMe()返回的值不是一样的吗?首先,我们调用
CreateObject(foo),这会返回一个MyFoo类型的对象. 然后我们调用MyFoo::setValue(7). 最后,我们调用MyFoo::getValue() 和
MyFoo::getValueFromMe(), 期望得到返回值7.当然,如果我们在任何情况下都得到7, 以上这个例子将不是本书中最没有意义的例
子. 所以我相信你已经猜到—我们得不到两个7这样的结果.但是我们将得到什么结果,并且更重要地,为什么呢?我们将得到的结果
分别是7和5. 至于为什么—--有三个很好的理由.首先,看构造函数. 当在构造函数内部,我们在this和this->me间建立引用. 换句
话说,this和this->me是同个东西. 但是我们是在构造函数内. 当构造函数结束,PHP要重新建立对象(new MyFoo的结果,第28行)分
配给$obj. 因为对象没有特殊化对待,就像其它任何数据类型一样,赋值X给Y意味着Y是X的一个副本. 也就是说,obj将是new MyFoo
的一个副本,而new MyFoo是一个存在于构造函数的对象. Obj->me怎么样呢? 因为它是一个引用,它原封不动仍然指向原来的对象
—this. Voila-obj和obj->me不再是同个东西了—改变其中一个另一个不变.以上是第一条理由. 还有其它类似于第一条的理由.
奇迹般地我们打算克服实例化对象这个问题(第28行). 一旦我们把CreateObject返回的值赋给global_object,我们仍然要撞上相
同的问题—global_object将变成返回值的一个副本,并且再次地,global_object和global_object->me将不再相同. 这就是第二条
理由.但是,事实上我们还走不了那么远— 一旦CreateObject返回$obj,我们将破坏引用(第34行) . 这就是第三条理由.那么,我们
如何改正这些? 有两个选择. 一是在所有地方增加&符号,就像例6.22那样(第24, 28, 31, 37行). 二.如果你幸运地使用上了
PHP5,你可以忘了以上这一切,PHP5会自动为你考虑这些. 如果你想知道PHP5是如何考虑这些问题的,继续阅读下去.Listing 6.22
WTMA syndrome in PHP 4 PHP4中的WTMA综合症1    class MyFoo { 2        function MyFoo() 3        { 4           
$this->me = &$this; 5            $this->value = 2; 6        } 7 8        function setValue($val) 9        { 10           
$this->value = $val; 11        } 12 13        function getValue() 14        { 15            return $this->value;
16        } 17 18        function getValueFromMe() 19        { 20            return $this->me->value; 21        }
22    }; 23 24        function &CreateObject($class_type) 25        { 26            switch ($class_type) { 27                
case foo: 28                    $obj =& new MyFoo(); 29                    break; 30                case bar: 31                    
$obj =& new MyBar(); 32                    break; 33            } 34            return $obj; 35        } 36 37        
$global_obj =& CreateObject (foo); 38        $global_obj->setValue(7); 39 40        print Value is  .
$global_obj->getValue() . \n; 41        print Value is  . $global_obj->getValueFromMe() . \n; PHP5是第一个把对象
看成与其它类型数据不同的PHP版本. 从用户的角度看,这证明它非常明白的方式—在PHP5中,对象总是通过引用来传递,而其它类
型数据(如integer,string,array)都是通过值来传递. 最显著地,没有必要再用&符号来表示通过引用来传递对象了.面向对象编程
广泛利用了对象网络和对象间的复杂关系,这些都需要用到引用. 在PHP的前些版本中,需要显示地指明引用. 因此, 现在默认用引
用来移动对象,并且只有在明确要求复制时才复制对象,这样比以前更好.它是如何实现的呢?在PHP5之前,所有值都存在一个名为
zval(Zend Value)的特殊结构里. 这些值可以存入简单的值,如数字和字符串,或复杂的值如数组和对象. 当值传给函数或从函数
返回时,这些值会被复制,在内存的另一个地址建立一个带有相同内容的结构.在PHP5中,值仍存为zval结构中,但对象除外. 对象存
在一个叫做Object Store的结构里,并且每个对象有一个不同的ID. Zval中,不储存对象本身,而是存着对象的指针. 当复制一个持
有对象的zval结构,例如我们把一个对象当成参数传给某个函数,我们不再复制任何数据. 我们仅仅保持相同的对象指针并由另一
个zval通知现在这个特定的对象指向的Object Store. 因为对象本身位于Object Store,我们对它所作的任何改变将影响到所有持
有该对象指针的zval结构.这种附加的间接作用使PHP对象看起来就像总是通过引用来传递,用透明和有效率的方式. 使用PHP5,我
们现在可以回到示例6.21,除去所有的&符号, 一切代码都仍然可以正常工作.当我们在构造函数(第4行)中持有一个引用时一个&符
号都不用.  


转自:  http://edu.chinaz.com
Jgwy.Com - Free Web Hosting Guide & Directory In China since 2001! Jgwy.Net-Jglt.Net
 楼主| 发表于 2005 年 10 月 8 日 15:42:44 | 显示全部楼层
【腾讯云】2核2G云服务器新老同享 99元/年,续费同价

第十五节--Zend引擎的发展 -- Classes and Objects in PHP5 [15]

  第十五节--Zend引擎的发展本章的最后一节,Zeev讨论了Zend引擎带来的对象模型,特别提到它与PHP的前几个版本中的模型有什么
不同.当1997年夏天,我们开发出PHP3, 我们没有计划要使PHP具备面向对象的能力. 当时没有任何与类和对象有关的想法. PHP3是
一个纯粹面向过程的语言. 但是,在1997.8.27的晚上PHP3 alpha版中增加了对类的支持. 增加一个新特性给PHP,当时仅需要极少
的讨论,因为当时探索PHP的人太少. 于是从1997年八月起, PHP迈出了走向面向对象编程语言的第一步.确实,这只是第一步. 因为
在这个设计中只有极少的相关的想法,对于对象的支持不够强大. 这个版本中使用对象仅是访问数组的一个很酷的方法而已. 取代
使用$foo[“bar”],你可以使用看起来更漂亮的$foo->bar. 面向对象方法的主要的优势是通过成员函数或方法来储存功能. 例子
6.18中显示了一个典型的代码块. 但是它和例6.19中的做法其实并没有太大不同.Listing 6.18 PHP 3 object-oriented
programming PHP3中的面向对象编程value;        }    }    $obj = new Example();    $obj-&gtrintValue(); ?> Listing
6.19 PHP 3 structural programming PHP3 PHP3中的结构化编程 以上我们在类中写上两行代码,或者显示地传递数组给函数. 但
考虑到PHP3中这两种选择并没有任何不同,我们仍然可以仅把对象模型当成一种”语法上的粉饰”来访问数组. 想要用PHP来进行
面向对象开发的人们,特别是想使用设计模式的人,很快就发现他们碰壁了. 幸运地,当时(PHP3时代)没有太多人想用PHP来进行面
向对象开发.PHP4改变了这种情况. 新的版本带来了引用(reference)的概念, 它允许PHP的不同标识符指向内存中的同一个地址.
这意味着你可以使用两个或更多的名称来给同一个变量命名,就像例6.20那样.Listing 6.20 PHP 4 references PHP4中的引用 由
于构建一个指向彼此的对象网络是所有面向对象设计模式的基础,这个改进具有非常重大的意义.当引用允许建立更多强大的面向
对象应用程序, PHP对待对象和其它类型数据相同的做法带给开发者极大的痛苦.就像任何PHP4的程序员将会告诉你的, 应用程序
将会遭遇WTMA(Way Too Many Ampersands过多&)综合症. 如果你想构建一个实际应用,你会感到极为痛苦,看看例6.21你就明
白.Listing 6.21 Problems with objects in PHP 4 PHP4中使用对象的问题1    class MyFoo { 2        function MyFoo() 3        
{ 4            $this->me = &$this; 5            $this->value = 5; 6        } 7 8        function setValue($val) 9        
{ 10            $this->value = $val; 11        } 12 13        function getValue() 14        { 15           
return $this->value; 16        } 17 18        function getValueFromMe() 19        { 20            return $this->
me->value; 21        } 22    } 23 24        function CreateObject($class_type) 25        { 26            switch
($class_type) { 27                case foo: 28                    $obj = new MyFoo(); 29                    
break; 30                case bar: 31                    $obj = new MyBar(); 32                    break; 33           
} 34            return $obj; 35        } 36 37        $global_obj = CreateObject (foo); 38        $global_obj->
setValue(7); 39 40        print Value is  . $global_obj->getValue() . \n; 41        print Value is  .
$global_obj->getValueFromMe() . \n; 让我们一步步来讨论. 首先,有一个MyFoo类.在构造函数里,我们给$this->me一个引用,
并设定我们有其它三个成员函数: 一个设定this->value的值;一个返回this->value的值;另一个返回this->value->me的值. 但
是--$this不是相同的东西吗? MyFoo::getValue()和MyFoo::getValueFromMe()返回的值不是一样的吗?首先,我们调用
CreateObject(foo),这会返回一个MyFoo类型的对象. 然后我们调用MyFoo::setValue(7). 最后,我们调用MyFoo::getValue() 和
MyFoo::getValueFromMe(), 期望得到返回值7.当然,如果我们在任何情况下都得到7, 以上这个例子将不是本书中最没有意义的例
子. 所以我相信你已经猜到—我们得不到两个7这样的结果.但是我们将得到什么结果,并且更重要地,为什么呢?我们将得到的结果
分别是7和5. 至于为什么—--有三个很好的理由.首先,看构造函数. 当在构造函数内部,我们在this和this->me间建立引用. 换句
话说,this和this->me是同个东西. 但是我们是在构造函数内. 当构造函数结束,PHP要重新建立对象(new MyFoo的结果,第28行)分
配给$obj. 因为对象没有特殊化对待,就像其它任何数据类型一样,赋值X给Y意味着Y是X的一个副本. 也就是说,obj将是new MyFoo
的一个副本,而new MyFoo是一个存在于构造函数的对象. Obj->me怎么样呢? 因为它是一个引用,它原封不动仍然指向原来的对象
—this. Voila-obj和obj->me不再是同个东西了—改变其中一个另一个不变.以上是第一条理由. 还有其它类似于第一条的理由.
奇迹般地我们打算克服实例化对象这个问题(第28行). 一旦我们把CreateObject返回的值赋给global_object,我们仍然要撞上相
同的问题—global_object将变成返回值的一个副本,并且再次地,global_object和global_object->me将不再相同. 这就是第二条
理由.但是,事实上我们还走不了那么远— 一旦CreateObject返回$obj,我们将破坏引用(第34行) . 这就是第三条理由.那么,我们
如何改正这些? 有两个选择. 一是在所有地方增加&符号,就像例6.22那样(第24, 28, 31, 37行). 二.如果你幸运地使用上了
PHP5,你可以忘了以上这一切,PHP5会自动为你考虑这些. 如果你想知道PHP5是如何考虑这些问题的,继续阅读下去.Listing 6.22
WTMA syndrome in PHP 4 PHP4中的WTMA综合症1    class MyFoo { 2        function MyFoo() 3        { 4           
$this->me = &$this; 5            $this->value = 2; 6        } 7 8        function setValue($val) 9        { 10           
$this->value = $val; 11        } 12 13        function getValue() 14        { 15            return $this->value;
16        } 17 18        function getValueFromMe() 19        { 20            return $this->me->value; 21        }
22    }; 23 24        function &CreateObject($class_type) 25        { 26            switch ($class_type) { 27                
case foo: 28                    $obj =& new MyFoo(); 29                    break; 30                case bar: 31                    
$obj =& new MyBar(); 32                    break; 33            } 34            return $obj; 35        } 36 37        
$global_obj =& CreateObject (foo); 38        $global_obj->setValue(7); 39 40        print Value is  .
$global_obj->getValue() . \n; 41        print Value is  . $global_obj->getValueFromMe() . \n; PHP5是第一个把对象
看成与其它类型数据不同的PHP版本. 从用户的角度看,这证明它非常明白的方式—在PHP5中,对象总是通过引用来传递,而其它类
型数据(如integer,string,array)都是通过值来传递. 最显著地,没有必要再用&符号来表示通过引用来传递对象了.面向对象编程
广泛利用了对象网络和对象间的复杂关系,这些都需要用到引用. 在PHP的前些版本中,需要显示地指明引用. 因此, 现在默认用引
用来移动对象,并且只有在明确要求复制时才复制对象,这样比以前更好.它是如何实现的呢?在PHP5之前,所有值都存在一个名为
zval(Zend Value)的特殊结构里. 这些值可以存入简单的值,如数字和字符串,或复杂的值如数组和对象. 当值传给函数或从函数
返回时,这些值会被复制,在内存的另一个地址建立一个带有相同内容的结构.在PHP5中,值仍存为zval结构中,但对象除外. 对象存
在一个叫做Object Store的结构里,并且每个对象有一个不同的ID. Zval中,不储存对象本身,而是存着对象的指针. 当复制一个持
有对象的zval结构,例如我们把一个对象当成参数传给某个函数,我们不再复制任何数据. 我们仅仅保持相同的对象指针并由另一
个zval通知现在这个特定的对象指向的Object Store. 因为对象本身位于Object Store,我们对它所作的任何改变将影响到所有持
有该对象指针的zval结构.这种附加的间接作用使PHP对象看起来就像总是通过引用来传递,用透明和有效率的方式. 使用PHP5,我
们现在可以回到示例6.21,除去所有的&符号, 一切代码都仍然可以正常工作.当我们在构造函数(第4行)中持有一个引用时一个&符
号都不用.  


转自:  http://edu.chinaz.com
Jgwy.Com - Free Web Hosting Guide & Directory In China since 2001! Jgwy.Net-Jglt.Net
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|金光论坛

GMT+8, 2024 年 11 月 20 日 15:35 , Processed in 0.124535 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表