PHP變量 之 對象範例變量

在 PHP 和 JavaScript 中(也許另有其他言語),變量內所保留的值分為 基礎範例值援用範例值

$obj = new stdClass;

若一個變量是一個對象,那末該變量保留的就是一個援用範例的值,即變量中現實保留的是堆內存中對象的地點,而不是對象的實體;若變量為其他範例,則保留的是基礎範例值,而不是援用地點。這一點須要特別注意,由於我們能夠會碰到以下幾種狀況,不清楚道理能夠致使失足。

賦值

$obj_1 = new stdClass;
$obj_2 = $obj_1;
$obj_1->name = 'Xavier';

var_dump($obj_1->name, $obj_2->name);
var_dump($obj_1, $obj_2);

輸出:

string(6) "Xavier"

string(6) "Xavier"

object(stdClass)#1 (1) {
  ["name"]=>
  string(6) "Xavier"
}

object(stdClass)#1 (1) {
  ["name"]=>
  string(6) "Xavier"
}

我們發明 obj_2name 也發作的轉變,緣由是 obj_1obj_2 指向同一個對象 #1 ,由於在第二行中,我們將 obj_1 所指向的對象的地點賦給了 obj_2

通報參數

我們來看這段代碼:

function setName($obj) {
    $obj->name = 'Xavier';
}

$person = new stdClass;
setName($person);
var_dump($person->name); // 輸出 string(6) "Xavier"

若變量為一個對象,那末當它作為參數通報給一個函數時,一樣,通報的是一個對象地點,而不是拷貝了一個新的對象實體給參數 $obj 。如許,函數內部並沒有 return 新的東西出來但轉變了外部的狀況 的這類狀況就變得好邃曉了。

接下來,請看這段代碼:

function setName($obj) {
    $obj->name = 'Xavier';
    $obj = new stdClass;
    $obj->name = 'Zhao';
}

$person = new stdClass;
setName($person);
var_dump($person->name); // 輸出了 string(6) "Xavier" 而不是 string(6) "Zhao"

末了的輸出效果能夠會讓很多人會迷惑,他們的頭腦多是如許的:

  1. 我將 person 對象的援用地點通報給 obj參數
  2. 在函數內部第一行,依據 obj 的援用地點,我將函數外部對象的 name 屬性設置成了 "Xavier"
  3. 在第二行,我將一個新的對象賦給了 obj ,既然 obj 為函數外部對象的援用,那末外部對象也肯定變為了這個新的對象
  4. 然後我再給這個新的對象設置新的 name 屬性 "zhao" ,嗯,如許外部對象的 name 肯定也變成了 "zhao"

假如你想的和上方雷同,那可就大錯特錯了,緣由在於對通報參數的歷程的毛病邃曉。

起首,我們應當邃曉,將一個變量作為參數通報給函數 能夠邃曉為 將誰人變量保留的值 複製一份給 函數的參數(參數即函數局限的局部變量) 。當函數實行時,外部變量函數參數(局部變量) 是同時存在於內存中的,而且二者是互相自力的,雖然二者所保留的值是雷同的;函數參數(局部變量) 會在函數實行終了后被燒毀。

邃曉了上述道理,那末我們從新來看那段代碼:

  1. 函數的 obj 變量在函數內第一行保留的是函數外部 person 變量所保留的值,也就是外部對象的地點
  2. 但到了第二行,obj 變量所保留的值變成了新創建的對象的地點,obj 的指向發作了轉變,而本來的外部對象照舊存在而且只被 person 一個變量援用,所以在第三行的行動並沒有影響到 person 所指向的誰人對象。新創建的對象在函數實行以後被燒毀。

所以有代碼中解釋的輸出效果。

    原文作者:Xavier
    原文地址: https://segmentfault.com/a/1190000014525684
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞