2010-02-05 66 views
19

我不是PHP程序員(但知道其他語言),並且我想了解一個在PHP(5.1.6)中完成的網頁,以便做一些更改。PHP「&」運算符

頁面有以下代碼(簡化):

$db_hosts = array(); 
$sql = 'SELECT h.hostid, h.host FROM hosts h '; 

$db_items = DBselect($sql); 

while($db_item = DBfetch($db_items)){ 
    $name = $db_item['host']; 
    $db_host = &$db_hosts[$db_item['hostid']]; 
} 

我想了解的最後一行,$db_host = &$db_hosts[$db_item['hostid']];

它似乎是創建一個新的變量,$db_host,並將其中的東西,但我不明白&$db_hosts

我有疑問,因爲據我所知,$db_hosts是一個空的數組。

我發現thisthis,但我不是很確定,因爲在這些環節中,運營商是「= &」,並在代碼中,運營商連接到變量「= $ & db_hosts」(它有一個介於=和&之間的空間)。

因爲我試圖修改它並沒有獲得成功,我認爲這是更好地尋求幫助......

回答

25

這些是引用,它們類似於C或C++中的「指針」。

更多信息請見PHP manual

在這種情況下,由於$db_hosts是空的,構建$db_hosts[$db_item['hostid']]將創建一個新的陣列上的$db_item['hostid']指數的空項目,並返回該項目的引用,使得$db_host充當一個「別名」不管是什麼$db_hosts[$db_item['hostid']]目前。

+0

這是正確的。我一次做了太多事情,回答太快了:-) – Josh 2010-02-05 19:53:05

+6

而且,正如我們正在討論PHP參考資料時,鏈接到標題爲「不要使用PHP引用」的帖子是爲了 - http://schlueters.de/博客/檔案/ 125-Do-not-use-PHP-references.html – 2010-02-05 20:06:21

+2

有點糾正..他們實際上不像C中的指針.. http://www.php.net/manual/en/language。 references.arent.php – 2014-06-04 07:39:20

1

的&來得到一個變量的引用。它與C++等其他語言中的引用類似,但有一些顯着差異。請參閱PHP Manual's section on references

+0

你的@符號的思考。 – rook 2010-02-05 19:51:25

+1

@邁克爾布魯克斯:是的,對不起,我的回答太快了。我糾正了我的答案。 – Josh 2010-02-05 20:10:08

+3

儘管第一眼看起來似乎是合理的,但這是一個非常誤導性的答案:'&'沒有「獲取」引用,因爲引用本身並不存在(就像C指針那樣)。相反,最好將'=&'想象成一個將兩個變量連接在一起的運算符,並將相關語法(如foo(&$ bar))作爲寫入該賦值的方式。 – IMSoP 2013-09-28 14:11:26

2

&被用作參考。見是 http://php.net/manual/en/language.references.php什麼參考:

引用在PHP是 訪問由 不同的名稱相同的變量內容的手段。他們不像C 指針;例如你不能用 執行指針運算, 它們不是實際的內存地址, 等等。

4

將該變量指定爲引用使其在$ db_host的稍後更改時,$ db_hosts數組中的對應條目也會發生更改,反之亦然。

我已經看到在PHP中使用貨物崇拜風格的一些相當無意義的引用。也許這個需要,也許不需要 - 你必須看看程序的其餘部分。

9

&在PHP中用於表示參考文獻(see this manual section),但誤認爲它本身就是一個操作符。這就是爲什麼有些人更喜歡寫$foo =& $bar而不是$foo = &$bar - 它意味着同樣的事情,但強調「參考y-ness」是賦值的屬性,而不是變量的屬性。在某些編程語言(如C或C++)中,您可以「獲得對某個特定變量的引用;結果值可以作爲不同的實體傳遞,然後「解除引用」以找出它指向的位置。這是而不是 PHP引用是什麼。

取而代之的是,全部 PHP變量實際上是對稱爲zval的內部類型的引用。你不能直接操縱PHP中的zval,你也不能製作額外的間接層 - 每個變量都是對zval的引用,就是這樣。 (見警告:下面的對象。)

分配按引用($foo =& $bar),一個傳遞引用(function foo(&$bar) { ... }),或返回通過引用(return &$foo)做的是什麼告訴你想PHP兩個變量指向相同的zval。請注意,您並未將「變量」指向另一個變量 - 它們都是同樣「真實」的,並且調用unset()將使另一變量完全不變。

警告:對象

它經常被誤稱,自PHP5的對象是「總是通過引用傳遞」。事實是他們有一個間接尋址層額外的層,其中zval本身是一個指向特定對象的指針。這給了我們三種不同的東西,我們可以參考一下:在變量,在zval它指向,而對象是一個指向:

// Create an object, and point three variables at it in different ways: 
$foo = new stdClass; 
$bar_by_value = $foo; 
$bar_by_ref =& $foo; 

// Change the object: updates the object shared by all three variables 
$foo->value = 42; 
// Change the value (zval) of $foo: will update $bar_by_ref, 
// but $bar_by_value still points at the original object 
$foo = 42; 
// Change the variable itself: will never affect $bar_by_value or $bar_by_ref 
unset($foo); 
6

問題

什麼「 &「是指在這裏的PHP?

PHP「&」運營商

讓生活更容易,一旦我們習慣了它。(下面仔細檢查例子)

&通常會檢查在兩個$ a中置位和$ b被設置。

你甚至已經注意到這些調用是如何工作的嗎?

error_reporting(E_ERROR | E_WARNING | E_PARSE); 
    error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE); 
    error_reporting(E_ALL & ~E_NOTICE); 
    error_reporting(E_ALL); 

因此,所有上述的背後,是位運算符和位的遊戲。

其中一個有用的例子就是像下面給出的簡單配置,所以單個整數字段可以爲您存儲數千個連擊。

大多數人已經閱讀過文檔,但沒有真正瞭解這些按位運算符的真實世界用例。

的例子,是非常有用的日常PHP生活

<?php 

class Config { 

    // our constants must be 1,2,4,8,16,32,64 ....so on 
    const TYPE_CAT=1; 
    const TYPE_DOG=2; 
    const TYPE_LION=4; 
    const TYPE_RAT=8; 
    const TYPE_BIRD=16; 
    const TYPE_ALL=31; 

    private $config; 

    public function __construct($config){ 
     $this->config=$config; 

     if($this->is(Config::TYPE_CAT)){ 
      echo 'cat '; 
     } 
     if($this->is(Config::TYPE_DOG)){ 
      echo 'dog '; 
     } 
     if($this->is(Config::TYPE_RAT)){ 
      echo 'rat '; 
     } 
     if($this->is(Config::TYPE_LION)){ 
      echo 'lion '; 
     } 
     if($this->is(Config::TYPE_BIRD)){ 
      echo 'bird '; 
     } 
     echo "\n"; 
    } 

    private function is($value){ 
     return $this->config & $value; 
    } 
} 

new Config(Config::TYPE_ALL); 
// cat dog rat lion bird 
new Config(Config::TYPE_BIRD); 
//bird 
new Config(Config::TYPE_BIRD | Config::TYPE_DOG); 
//dog bird 
new Config(Config::TYPE_ALL & ~Config::TYPE_DOG & ~Config::TYPE_CAT); 
//rat lion bird 
+1

這是一個完全不同的運營商的好例子。它碰巧也拼寫成'&',但問題中的運算符是*的引用*,與按位運算無關。 – IMSoP 2017-04-03 14:30:04