php教程 php手册 PHP5.0对象模型探索之Zend引擎的发展

PHP5.0对象模型探索之Zend引擎的发展

Jun 21, 2016 am 08:59 AM
function obj this

  在这个系列文章的最后一部分,作者讨论了Zend引擎带来的对象模型,特别提到它与PHP的前几个版本中的模型有什么不同。

  当1997年夏天,发布的PHP3中没有计划要使PHP具备面向对象的能力. 当时没有任何与类和对象有关的想法. PHP3是一个纯粹面向过程的语言. 但是,在1997.8.27的晚上PHP3 alpha版中增加了对类的支持. 增加一个新特性给PHP,当时仅需要极少的讨论,因为当时探索PHP的人太少. 于是从1997年八月起, PHP迈出了走向面向对象编程语言的第一步.

  确实,这只是第一步. 因为在这个设计中只有极少的相关的想法,对于对象的支持不够强大. 这个版本中使用对象仅是访问数组的一个很酷的方法而已. 取代使用$foo[“bar”],你可以使用看起来更漂亮的$foo->bar. 面向对象方法的主要的优势是通过成员函数或方法来储存功能. 例子1中显示了一个典型的代码块. 但是它和例6.19中的做法其实并没有太大不同.

  Listing1 PHP 3 object-oriented programming PHP3中的面向对象编程

class Example
{
var $value = "some value";
function PrintValue()
{
print $this->value;
}
}
$obj = new Example();
$obj->PrintValue();
?>

  Listing2 PHP 3 structural programming PHP3 PHP3中的结构化编程

function PrintValue($arr)
{
print $arr["value"];
}

function CreateExample()
{
$arr["value"] = "some value";
$arr["PrintValue"] = "PrintValue";

return $arr;
}

$arr = CreateExample();

//Use PHP's indirect reference
$arr["PrintValue"]($arr);
?>

  以上我们在类中写上两行代码,或者显示地传递数组给函数. 但考虑到PHP3中这两种选择并没有任何不同,我们仍然可以仅把对象模型当成一种”语法上的粉饰”来访问数组.

  想要用PHP来进行面向对象开发的人们,特别是想使用设计模式的人,很快就发现他们碰壁了. 幸运地,当时(PHP3时代)没有太多人想用PHP来进行面向对象开发.

  PHP4改变了这种情况. 新的版本带来了引用(reference)的概念, 它允许PHP的不同标识符指向内存中的同一个地址. 这意味着你可以使用两个或更多的名称来给同一个变量命名,就像例3那样.

  Listing3 PHP 4 references PHP4中的引用

$a = 5;

//$b points to the same place in memory as $a $b与$a指向内存中同个地址
$b = &$a;

//we're changing $b, since $a is pointing to 改变$b,指向的地址改变
//the same place - it changes too $a指向的地址也改变
$b = 7;

//prints 7 输出7
print $a;
?>

  由于构建一个指向彼此的对象网络是所有面向对象设计模式的基础,这个改进具有非常重大的意义.当引用允许建立更多强大的面向对象应用程序, PHP对待对象和其它类型数据相同的做法带给开发者极大的痛苦.就像任何PHP4的程序员将会告诉你的, 应用程序将会遭遇WTMA(Way Too Many Ampersands过多&)综合症. 如果你想构建一个实际应用,你会感到极为痛苦,看看例3你就明白.

  Listing3 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行) . 这就是第三条理由。

  那么,我们如何改正这些? 有两个选择:一是在所有地方增加&符号,就像例4那样(第24, 28, 31, 37行)。二.如果你幸运地使用上了PHP5,你可以忘了以上这一切,PHP5会自动为你考虑这些。如果你想知道PHP5是如何考虑这些问题的,继续阅读下去。

  Listing4 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,我们现在可以回到示例3,除去所有的&符号, 一切代码都仍然可以正常工作。当我们在构造函数(第4行)中持有一个引用时一个&符号都不用。



본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

기능은 무슨 뜻인가요? 기능은 무슨 뜻인가요? Aug 04, 2023 am 10:33 AM

함수는 특정 기능을 포함하는 재사용 가능한 코드 블록으로, 입력 매개변수를 받아들이고 특정 작업을 수행하며 결과를 반환하는 것이 목적입니다. 코드 재사용성과 유지 관리성을 향상시키는 코드입니다.

Python에서 'enumerate()' 함수의 목적은 무엇입니까? Python에서 'enumerate()' 함수의 목적은 무엇입니까? Sep 01, 2023 am 11:29 AM

이번 글에서는 enumerate() 함수와 Python에서 “enumerate()” 함수의 목적에 대해 알아봅니다. enumerate() 함수란 무엇입니까? Python의 enumerate() 함수는 데이터 컬렉션을 매개변수로 받아들이고 열거형 객체를 반환합니다. 열거형 객체는 키-값 쌍으로 반환됩니다. 키는 각 항목에 해당하는 인덱스이고 값은 항목입니다. 구문 enumerate(iterable,start) 매개변수 iterable - 전달된 데이터 컬렉션은 iterablestart라는 열거형 개체로 반환될 수 있습니다. - 이름에서 알 수 있듯이 열거형 개체의 시작 인덱스는 start로 정의됩니다. 우리가 무시한다면

MySQL.proc 테이블의 역할과 기능에 대한 자세한 설명 MySQL.proc 테이블의 역할과 기능에 대한 자세한 설명 Mar 16, 2024 am 09:03 AM

MySQL.proc 테이블의 역할과 기능에 대한 자세한 설명 MySQL은 널리 사용되는 관계형 데이터베이스 관리 시스템으로, 개발자가 MySQL을 사용할 때 저장 프로시저(StoredProcedure)를 생성하고 관리하는 경우가 많습니다. MySQL.proc 테이블은 저장 프로시저의 이름, 정의, 매개변수 등을 포함하여 데이터베이스의 모든 저장 프로시저와 관련된 정보를 저장하는 매우 중요한 시스템 테이블입니다. 이번 글에서는 MySQL.proc 테이블의 역할과 기능에 대해 자세히 설명하겠습니다.

Vue.use 함수의 사용법과 기능 Vue.use 함수의 사용법과 기능 Jul 24, 2023 pm 06:09 PM

Vue.use 함수의 사용법 및 기능 Vue는 많은 유용한 기능을 제공하는 널리 사용되는 프런트 엔드 프레임워크입니다. 그 중 하나는 Vue 애플리케이션에서 플러그인을 사용할 수 있게 해주는 Vue.use 기능입니다. 이 기사에서는 Vue.use 함수의 사용법과 기능을 소개하고 몇 가지 코드 예제를 제공합니다. Vue.use 함수의 기본 사용법은 매우 간단합니다. Vue가 인스턴스화되기 전에 호출하고 매개변수로 사용하려는 플러그인을 전달하면 됩니다. 다음은 간단한 예입니다. //플러그인 소개 및 사용

PHP의 file_exists() 함수 PHP의 file_exists() 함수 Sep 14, 2023 am 08:29 AM

file_exists 메소드는 파일이나 디렉토리가 존재하는지 확인합니다. 확인할 파일이나 디렉터리의 경로를 인수로 받아들입니다. 용도는 다음과 같습니다. 파일을 처리하기 전에 파일이 존재하는지 알아야 할 때 유용합니다. 이렇게 하면 새 파일을 만들 때 이 기능을 사용하여 파일이 이미 존재하는지 알 수 있습니다. 구문 file_exists($file_path) 매개변수 file_path - 존재 여부를 확인할 파일 또는 디렉터리의 경로를 설정합니다. 필수의. return file_exists() 메서드가 반환됩니다. 파일이나 디렉터리가 존재하면 TrueFalse를 반환하고, 파일이나 디렉터리가 존재하지 않으면 예를 들어 "candidate.txt" 파일을 확인하고 파일이

obj는 어떤 형식인가요? obj는 어떤 형식인가요? Feb 01, 2023 pm 03:01 PM

obj는 3D 모델 형식 파일 또는 프로그램 컴파일 중간 코드 파일을 참조할 수 있습니다. obj3D 모델 파일은 보기, 편집 및 수정을 위해 워드패드로 직접 열 수 있는 텍스트 파일입니다. 여기에는 애니메이션, 재료 속성, 텍스처 경로, 역학, 입자 및 기타 정보가 포함되어 있지 않습니다. obj 객체 파일은 일반적으로 프로그램에 의해 컴파일된 바이너리 파일이며, 링커와 리소스 파일을 통해 연결되어 실행 파일이 됩니다.

js 함수의 사용법은 무엇입니까 js 함수의 사용법은 무엇입니까 Oct 07, 2023 am 11:25 AM

js 함수 함수의 사용법은 다음과 같습니다. 1. 함수 호출 3. 함수 반환 값 6. 함수 범위 8.

PHP에서 SOA 함수를 사용하는 방법 PHP에서 SOA 함수를 사용하는 방법 May 18, 2023 pm 01:10 PM

인터넷의 발전과 함께 SOA(서비스 지향 아키텍처)는 오늘날의 기업 수준 시스템에서 중요한 기술 아키텍처가 되었습니다. SOA 아키텍처의 서비스는 재사용, 재구성 및 확장이 가능하며 시스템 개발 및 유지 관리 프로세스도 단순화됩니다. 널리 사용되는 웹 프로그래밍 언어인 PHP는 SOA 구현을 위한 일부 기능 라이브러리도 제공합니다. 다음으로 PHP에서 SOA 기능을 사용하는 방법을 자세히 설명하겠습니다. 1. SOA의 기본 개념은 분산 시스템 개발 아이디어와 아키텍처입니다.

See all articles