国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > PHP > 正文

PHP5.0對象模型探索之Zend引擎的發展

2024-05-04 23:04:16
字體:
來源:轉載
供稿:網友
  在這個系列文章的最后一部分,作者討論了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行)中持有一個引用時一個&符號都不用。,歡迎訪問網頁設計愛好者web開發。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 岑巩县| 广河县| 阆中市| 海伦市| 长宁县| 通许县| 宝清县| 松阳县| 莲花县| 九江市| 奎屯市| 平凉市| 乐平市| 遂昌县| 阳泉市| 河南省| 雷山县| 都昌县| 岳阳市| 怀来县| 南木林县| 常宁市| 佛冈县| 大石桥市| 神木县| 克拉玛依市| 扬中市| 安丘市| 林芝县| 无锡市| 阳泉市| 广汉市| 玉山县| 舞钢市| 从化市| 剑阁县| 天峻县| 饶平县| 新安县| 喜德县| 方山县|