最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

PHP 引用的概念

 更新時間:2021年04月30日 09:38:24   作者:硬核項目經(jīng)理  
這篇文章主要介紹了PHP的中引用的概念,幫助大家更好的理解和學習使用PHP,感興趣的朋友可以了解下

什么是引用?

在 PHP 中引用意味著用不同的名字訪問同一個變量內(nèi)容。它不是C的指針,保存的并不是內(nèi)存地址,無法進行指針運算。引用只是符號表的別名。就像 Unix 系統(tǒng)中的硬鏈接, Windows 系統(tǒng)中的快捷方式。

上面是官方手冊中的原文,怎么說呢,引用其實和我們印象中的C里面的指針并不是相同的概念。指針是針對真實內(nèi)存的操作,引用是針對指向這個內(nèi)存的符號表的操作。還是從操作系統(tǒng)的快捷方式來說,快捷方式是可以刪的,這就是PHP的引用。而C不僅刪了快捷方式,還把原文件也給刪了,這就是C的指針操作。

// 引用不是指針
$a = 1;
$b = &$a;
echo $a, '===', $b, PHP_EOL;
unset($b);
echo $a, '===', $b, PHP_EOL;

上面的代碼是在PHP中,我們把b變量指向b變量指向a,作為a的引用變量。然后刪除a的引用變量。然后刪除b,對$a沒有任何影響。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    // C 中的指針和引用
    int a = 1;
    int* b = &a;
    printf("%i\n", a); // 1
    free(b); // free b
    printf("%i\n", a); //get error: *** error for object 0x7fff6350da08: pointer being freed was not allocated
    return 0;
}

而C中的引用指針就不行了,我們把b變量刪掉后,再打印a變量就直接報錯了。

雖然說PHP的底層也是C寫得,但我們都知道C中的指針是出了名的變態(tài),沒有一定的功底非常容易出錯。所以PHP的開發(fā)者沒有暴露C的原始指針能力,而是采用了和Java之類的類似的引用能力。這也是現(xiàn)代語言的特性,不需要我們過多的關(guān)注過于底層的能力,而將更多的時間放在業(yè)務(wù)實現(xiàn)上。

引用在數(shù)組和對象中的使用

如果具有引用的數(shù)組被拷貝,其值不會解除引用。對于數(shù)組傳值給函數(shù)也是如此。

$arr1 = ["a", "b"];
$t1 = &$arr1[1];
$arr2 = $arr1;
$arr2[1] = "c";
var_dump($arr1);

// array(2) {
//     [0]=>
//     string(1) "a"
//     [1]=>
//     &string(1) "c"
// }

$arr1 = ["a", "b"];
$t1 = &$arr1[1];
unset($t1); // unset 掉引用
$arr2 = $arr1;
$arr2[1] = "c";
var_dump($arr1);

// array(2) {
//     [0]=>
//     string(1) "a"
//     [1]=>
//     string(1) "b"
// }

這個其實挺有意思的,我們對比這兩個例子可以看出一個問題,t變量指向t變量指向arr[1]的引用。arr2直接=這個arr2直接=這個arr1,沒有使用引用,然后arr2修改了arr2修改了arr2[1]的內(nèi)容,arr1相應(yīng)的內(nèi)容也發(fā)生了改變,如果unset掉arr1相應(yīng)的內(nèi)容也發(fā)生了改變,如果unset掉t變量,則$arr1相應(yīng)的內(nèi)容就不會發(fā)生改變。對此,我在文檔中找到了下面的解釋:

由于PHP內(nèi)部工作的特殊性,如果對數(shù)組的單個元素進行引用,然后復制數(shù)組,無論是通過賦值還是通過函數(shù)調(diào)用中的值傳遞,都會將引用復制為數(shù)組的一部分。這意味著對任一數(shù)組中任何此類元素的更改都將在另一個數(shù)組(和其他引用中)中重復,即使數(shù)組具有不同的作用域(例如,一個是函數(shù)內(nèi)部的參數(shù),另一個是全局的)!在復制時沒有引用的元素,以及在復制數(shù)組后分配給其他元素的引用,將正常工作(即獨立于其他數(shù)組)。

不僅僅是數(shù)組,對象的引用也會有一些好玩的問題。

$o1 = new stdClass();
$o1->a = 'a';
var_dump($o1);
// object(stdClass)#1 (1) {
//   ["a"]=>
//   string(1) "a"
// }

$o2 = &$o1;
$o3 = $o1;

$o2->a = 'aa';

var_dump($o1);
// object(stdClass)#1 (1) {
//   ["a"]=>
//   string(2) "aa"
// }

var_dump($o3); // $o2修改了$a為'aa',$o3也變成了'aa'
// object(stdClass)#1 (1) {
//   ["a"]=>
//   string(2) "aa"
// }

$o1->a = 'aaa';
$o1 = null;
var_dump($o2); // $o2引用變成了null
// NULL

var_dump($o3); // $o3不僅引用還存在,并且$a變成了'aaa'
// object(stdClass)#1 (1) {
//   ["a"]=>
//   string(3) "aaa"
// }

上面例子中有三個對象,o1、o1、o2、o3,其中,o3,其中,o2是對o1的引用,o1的引用,o3是直接賦值為o1。對o1。對o2屬性的操作不僅會反映在o1中,也會反映到o1中,也會反映到o3中。其實我們之前專門有一篇文章就講的這個問題,首先對象默認賦值就是引用,其次這個例子很好地證明了引用就是一個符號表的綁定。刪除了快捷方式對原始對象和其他快捷方式?jīng)]有任何影響。

引用的傳遞

關(guān)于引用在方法參數(shù)上的傳遞,最重要的是記住兩點:一是方法內(nèi)部修改了變量外部也會變,這是引用的特性嘛;二是只能傳遞變量、New 語句、從函數(shù)中返回的引用三種類型。

error_reporting(E_ALL);
function foo(&$var)
{
    $var++;
    echo 'foo:', $var;
}
function bar() // Note the missing &
{
    $a = 5;
    return $a;
}
foo(bar()); // 自 PHP 5.0.5 起導致致命錯誤,自 PHP 5.1.1 起導致嚴格模式錯誤
            // 自 PHP 7.0 起導致 notice 信息,Notice: Only variables should be passed by reference
foo($a = 5); // 表達式,不是變量, Notice: Only variables should be passed by reference
// foo(5); // 導致致命錯誤 !5是個常量!

///////////////////////////////
// 正確的傳遞類型
$a = 5;
foo($a); // 變量

function &baz()
{
    $a = 5;
    return $a;
}
foo(baz()); // 從函數(shù)中返回的引用

function foo1(&$var)
{
    print_r($var);
}
foo1(new stdClass()); // new 表達式

引用的返回

引用的返回并不是經(jīng)常使用的一個能力。文檔中的原文是:不要用返回引用來增加性能,引擎足夠聰明來自己進行優(yōu)化。僅在有合理的技術(shù)原因時才返回引用!

$a = 1;
function &test(){
    global $a;
    return $a;
}

$b = &test($a);
$b = 2;
echo $a, PHP_EOL;

當你想要返回一個引用變量的時候,一定要給方法定義和方法調(diào)用的時候都使用&符號。這個是需要注意的點。當其他地方修改原本的變量值或者返回的變量值經(jīng)過修改后,都會影響到所有調(diào)用這個值的地方。所以說,引用的返回是比較危險的,因為你不清楚什么時候在什么地方這個值可能發(fā)生了修改,對于bug的排查會非常困難。

引用的取消

取消引用其實就是直接unset掉變量就可以了。但是一定要記住,PHP中的引用是指向的符號表,對原始真實的值是不起作用的,所以即使unset掉了最原始的那個變量,對其它引用賦值的變量也不會有影響??!

$a = 1;
$b = &$a;
$c = &$b;
$b = 2;
echo '定義引用后:', $a, '===', $b, '===', $c, PHP_EOL;

unset($b);
$b = 3;
echo '取消$b的引用,不影響$a、$c:', $a, '===', $b, '===', $c, PHP_EOL;

$b = &$a;
unset($a);
echo '取消$a,不影響$b、$c:', $a, '===', $b, '===', $c, PHP_EOL;

// 定義引用后:2===2===2
// 取消$b的引用:2===3===2
// 取消$a,不影響$c:===3===2


$a = 1;
$b = & $a;
$c = & $b; // $a, $b, $c reference the same content '1'

$a = NULL; // All variables $a, $b or $c are unset
echo '所有引用成空:', $a, '===', $b, '===', $c, PHP_EOL;

總結(jié)

這一次算是比較徹底的把引用說了個透。關(guān)于PHP的引用只要記住了它的定義就非常好理解了,最直觀的就是當成是操作系統(tǒng)的快捷方式就好了,并沒有我們想象中的那么難,和C的指針相比真的只是娃娃級別,多多練習多多復習自然就能很好地掌握使用啦!

測試代碼: github.com/zhangyue050…

以上就是PHP的中引用的概念的詳細內(nèi)容,更多關(guān)于PHP 引用的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • PHP進行批量任務(wù)處理不超時的解決方法

    PHP進行批量任務(wù)處理不超時的解決方法

    這篇文章主要介紹了PHP進行批量任務(wù)處理不超時的解決方法,結(jié)合實例形式簡單分析了php結(jié)合ajax進行異步處理實現(xiàn)批量任務(wù)不超時的相關(guān)技巧,需要的朋友可以參考下
    2016-07-07
  • 劣質(zhì)的PHP代碼簡化

    劣質(zhì)的PHP代碼簡化

    下面這一小段“劣質(zhì)”的PHP代碼是一道簡化了的測試題。這種問題就像在問:你該怎樣優(yōu)化這段代碼?
    2010-02-02
  • PHP實現(xiàn)的創(chuàng)建帶logo圖標二維碼生成類詳解

    PHP實現(xiàn)的創(chuàng)建帶logo圖標二維碼生成類詳解

    這篇文章主要介紹了PHP實現(xiàn)的創(chuàng)建帶logo圖標二維碼生成類,結(jié)合實例形式分析了可生成帶logo的二維碼工具類PHPQRCode.class.php相關(guān)參數(shù)、功能與使用技巧,需要的朋友可以參考下
    2018-07-07
  • PHP中的cookie

    PHP中的cookie

    PHP中的cookie...
    2006-11-11
  • Yii學習總結(jié)之安裝配置

    Yii學習總結(jié)之安裝配置

    本文是Yii學習總結(jié)系列文章的第一篇,主要給大家介紹下YII的簡單介紹及安裝和配置,有需要的小伙伴參考下吧。
    2015-02-02
  • php實現(xiàn)根據(jù)詞頻生成tag云的方法

    php實現(xiàn)根據(jù)詞頻生成tag云的方法

    這篇文章主要介紹了php實現(xiàn)根據(jù)詞頻生成tag云的方法,涉及php分析與操作字符串以及標簽云的生成技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-04-04
  • php自動獲取目錄下的模板的代碼

    php自動獲取目錄下的模板的代碼

    php自定義函數(shù)之自動獲取目錄下的模板的實現(xiàn)代碼,一般制作模板分離的管理系統(tǒng)需要用得到。
    2010-08-08
  • PHP之Swoole學習安裝教程

    PHP之Swoole學習安裝教程

    這篇文章主要介紹了PHP之Swoole學習安裝教程,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • 解析PHP中常見的mongodb查詢操作

    解析PHP中常見的mongodb查詢操作

    本篇文章是對PHP中常見的mongodb查詢操作進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • php中將一個對象保存到Session中的方法

    php中將一個對象保存到Session中的方法

    這篇文章主要介紹了php中將一個對象保存到Session中的方法,涉及php操作對象及session的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03

最新評論

广南县| 尉氏县| 定边县| 连山| 丁青县| 根河市| 垫江县| 雅江县| 柏乡县| 霍山县| 德令哈市| 陆河县| 保亭| 莲花县| 瑞丽市| 和平县| 长丰县| 岗巴县| 华容县| 神木县| 明光市| 三明市| 普宁市| 富民县| 兴文县| 梓潼县| 文成县| 报价| 常宁市| 平安县| 陇南市| 万安县| 抚松县| 岳西县| 庄浪县| 栖霞市| 文成县| 新和县| 辰溪县| 连城县| 南宁市|