在Zend引擎15开发
当1997的夏天,我们开发的东西,我们没有计划让PHP的面向对象的能力。没有相关的类和对象概念。PHP3是一个纯粹的面向过程的语言。然而,支持类1997.8.27在alpha版本PHP3。PHP的一个新特性,只需要很少讨论,因为人太少了。因此,从1997年8月开始探索PHP时,PHP是面向对象编程语言的第一步。
的确,这只是第一步。因为只有少数想法与此设计相关,不足以支持对象的使用。此版本的对象仅是访问数组的一种很酷的方式。您可以使用更漂亮的$ bar条,而不是使用。面向对象方法的主要优点是通过成员函数或方法来存储函数。示例中的6.18显示了一个典型的代码块。但是在6.19种情况下这样做实际上并没有太大的不同。
面向对象的清单6.18 PHP 3面向对象编程PHP3编程
类的实例
{
值一些值;
PrintValue()函数
{
打印$这个值;
}
}
$ obj =新例();
$ obj -> printvalue();
清单6.19中的PHP 3结构化程序设计结构化程序设计3 3
功能printvalue($ ARR)
{
打印数组{美元价值};
}
CreateExample()函数
{
美元的价值,{ =有价值;
$ ARR {printvalue=printvalue ;
返回的数组;
}
ARR = CreateExample(美元);
使用PHP的间接引用
$ ARR {printvalue}($ ARR);
以上,我们在课堂上写两行代码,或传递数组的功能,但考虑到在PHP3的两种选择是不一样的,我们仍然可以访问数组对象只是一个语法的粉饰。
想要使用PHP进行面向对象开发的人,特别是那些想要使用设计模式的人,很快就会发现自己陷入了困境。幸运的是,在那个时候,没有很多人在PHP3时代谁想用PHP开发的面向对象的。
PHP4的局面已改变。新版本带来了引用(引用)的概念,它允许PHP的不同标识符指向内存中相同的地址。这意味着可以使用两个或多个名称来命名相同的变量,如示例6.20所示。
清单6.20中的PHP 4引用PHP4基准
$ = 5;
$ B指向内存中的同一位置,$ $ B和$指向内存中相同的地址。
美元=美元;
我们正在更改$ B,因为$指向更改$,直接地址更改。
相同地址的地址-它也改变了$ A也改变了。
$ = 7;
打印7输出7
打印$;
由于建立了一个指向每一个对象的网络,是所有面向对象设计模式的基础,对提高参考价值具有重要意义。当允许构建更强大的面向对象应用程序时,PHP以同样的方式对待对象和其他类型的数据,这给开发人员带来了极大的痛苦。就像任何PHP4程序员会告诉你,这个应用会遇到西得克萨斯博物馆协会(太多的符号太多)综合征。如果你想建立一个实际的应用程序,你会感到巨大的痛苦,看6.21箱你就会明白。
清单6.21中的问题在PHP 4 PHP4对象使用对象的问题
类myfoo { 1
2 MyFoo()函数
{ 3
4美元;
5 $此值= 5;
6 }
七
8函数值(美元值)
{ 9
10 $;
11 }
十二
13个功能是()
{ 14
15返回$这个值;
16 }
十七
18 getvaluefromme()函数
{ 19
20返回$;
21 }
22 }
二十三
24函数的CreateObject(class_type美元)
{ 25
26开关($ class_type){
27例:
28美元=新myfoo(obj);
29打破;
30个案例:
31美元=新mybar(obj);
32打破;
33 }
34返回的对象;
35 }
三十六
37美元global_obj = CreateObject(foo);
38美元global_obj ->设定值(7);
三十九
40打印值是。global_obj美元-> getValue()。n;
41打印值是。global_obj美元-> getvaluefromme()。n;
让我们一步一步来讨论。首先,有一个myfoo类。在构造函数中,我们给出一个引用,并设置它。
我们还有三个其他成员函数:一组这个-值值;这个值的返回值;另一个返回这个值。但是,美元不是一回事:getValue(myfoo:)和myfoo:(getvaluefromme)返回的值是不一样的你
首先,我们叫CreateObject(foo),它将返回一个对象myfoo型。然后我们叫myfoo setValue(7):。最后,我们称myfoo getValue(),::::myfoo getvaluefromme(),并期望得到返回值7 ..
当然,如果我们在任何情况下得到7或更多,这个例子将不是本书中最无意义的例子。所以我相信你已经猜到我们不能得到两个7的结果。
但是,我们会得到什么,更重要的是,为什么呢
我们得到的结果是7和5,为什么有三个充分的理由。
首先,看看构造函数。在构造函数中,我们在这个和这个引用中设置。换句话说,这个和这个我是一样的。但是我们在构造函数中。当构造函数结束,PHP重新建立对象(新myfoo,第二十八)分配到$ obj。因为对象不是特殊的处理。像任何其他类型的数据,X分配到Y,Y是一份X。也就是说,是将一份新的myfoo,和新的myfoo是对象在对象->我的构造函数。因为它是一个参考,它仍然指向原始对象完整的这个。瞧OBJ和OBJ ->我不再是同一件事,改变一个另一个。
以上是第一个原因。还有其他类似的第一个原因。Miraculously, we intend to overcome this problem by instantiating an object (line twenty-eighth). 一旦我们有一个正确的返回值赋给global_object,我们还是要global_object将成为一个复制问题的返回值为一,一次又一次。global_object和global_object ->我是不一样的。这是第二个原因。
但是,事实上,我们不能走那么远,一旦CreateObject返回$ obj,我们将摧毁参考(第三十四线)。这是第三个原因。
那么,我们怎样纠正这两种选择呢。一个是增加所有地方的符号,比如6.22个案例中的符号(第二十四,28, 31, 37)。两。如果你足够幸运的话,使用PHP5,你可以忘记这一切,PHP5会自动为你如果你要考虑这些。知道PHP5是考虑这些问题,读一读。
清单6.22西得克萨斯博物馆协会综合征PHP 4 PHP4西得克萨斯博物馆协会综合征
类myfoo { 1
2 MyFoo()函数
{ 3
4美元;
5 $此值= 2;
6 }
七
8函数值(美元值)
{ 9
10 $;
11 }
十二
13个功能是()
{ 14
15返回$这个值;
16 }
十七
18 getvaluefromme()函数
{ 19
20返回$;
21 }
22 };
二十三
24函数的CreateObject(class_type美元)
{ 25
26开关($ class_type){
27例:
28美元=新myfoo(obj);
29打破;
30个案例:
31美元=新mybar(obj);
32打破;
33 }
34返回的对象;
35 }
三十六
37美元global_obj = CreateObject(foo);
38美元global_obj ->设定值(7);
三十九
40打印值是。global_obj美元-> getValue()。n;
41打印价值。($ global_obj -> getvaluefromme)。N;PHP5是第一个对象不同于其他类型的数据。从用户的角度来看的PHP版本,这证明它在PHP5中是非常明确的,客体总是参照转移,和其他类型的数据(如整数、字符串、数组)是通过值传递。最重要的是,没有必要使用符号来引用对象来表示对象。
面向对象编程广泛使用对象与对象网络之间的复杂关系,这些都需要参考。在PHP以前的版本中,需要显式指定引用。因此,现在默认使用移动对象,并且只在清晰的副本中复制,所以比以前更好。
它是怎么变成现实的
在PHP5中,所有的价值是一个变量(多值)的特殊结构。这些值可以存储在简单的值中,如数字和字符串,或复杂的值,如数组和对象。函数返回的职责是,这些值将被复制到另一个地址。包括建立同一内容结构的存款。
在PHP5中,价值仍然是zval结构,但有一个对象。除了对象调用对象存储结构,每个对象都有一个不同的ID. Zval,不存储对象本身,而是对象的指针。在zval结构复制的对象,如美国一个对象作为函数的参数,我们不复制任何数据。我们只是保持相同的对象指针和变量被另一个通知现在这个特定的对象指向的对象存储。因为对象本身位于对象存储,我们所做的任何更改将影响所有对象的指针变量结构。这种间接的效果使得额外的PHP对象看起来总是以引用的方式传递,具有透明和高效的方式。
随着PHP5,我们现在可以回到例子6.21,并删除所有的符号,所有的代码仍然可以正常工作。当我们在构造函数(第四行)中引用时,没有符号。