Я не программист на PHP (но знаю другие языки), и я пытаюсь понять веб-страницу, которая была сделана в PHP (5.1.6), чтобы внести некоторые изменения.
Страница имеет следующий код (упрощенный):
$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
– пустой массив.
Я нашел это и это , но я не совсем уверен, потому что в этих ссылках оператор «= &», а в коде оператор привязан к переменной «= & $ db_hosts» (у него есть пробел между = и &).
Поскольку я пытался изменить его и не добился успеха, я подумал, что лучше обратиться за помощью …
Это ссылки, и они похожи на «указатели» на C или C ++.
Дополнительная информация содержится в руководстве по PHP .
В этом случае, поскольку $db_hosts
пуст, конструкция $db_hosts[$db_item['hostid']]
создаст новый массив с пустым элементом в индексе $db_item['hostid']
и вернет ссылку на элемент, сделав $db_host
действует как «псевдоним» для любого $db_hosts[$db_item['hostid']]
в настоящее время.
&
используется по-разному в PHP для обозначения ссылок ( см. этот раздел руководства ), но вводить в заблуждение думать о нем как о собственном праве. Вот почему некоторые люди предпочитают писать $foo =& $bar
а не $foo = &$bar
– это означает одно и то же, но подчеркивает, что «reference-y-ness» является свойством назначения, а не переменные.
На некоторых языках программирования, таких как C или C ++, вы можете «получить ссылку на» конкретную переменную; результирующее значение может передаваться как отдельный объект, а затем «де-ссылку», чтобы узнать, где он указывает. Это не ссылки на PHP.
Вместо этого все переменные PHP на самом деле ссылаются на внутренний тип, называемый zval
. Вы не можете напрямую манипулировать zval
s в PHP и не можете создавать дополнительные слои косвенности – каждая переменная является ссылкой на zval
, и все. (См. Caveat: объекты ниже.)
Какое присваивание по ссылке ( $foo =& $bar
), pass-by-reference ( function foo(&$bar) { ... }
) или обратная ссылка ( return &$foo
) do говорит 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);
Вопрос :
Что означает «&» здесь в 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 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
Присвоение этой переменной в качестве ссылки делает так, что если позже в $ db_host будет изменено, соответствующая запись в массиве $ db_hosts также изменится, и наоборот.
Я видел довольно немного бессмысленное использование ссылок в PHP, стиль культа груза. Возможно, это нужно, возможно, нет – вам придется посмотреть на остальную часть программы.
&
используется как ссылка. Посмотрите, какие ссылки приведены в http://php.net/manual/en/language.references.php :
Ссылки на PHP – это средство доступа к одному и тому же содержимому переменной разными именами. Они не похожи на C-указатели; например, вы не можете выполнять арифметику указателей, используя их, они не являются фактическими адресами памяти и т. д.
&
Присваивает по ссылке .
& Используется для получения ссылки на переменную. Это похоже на ссылки на других языках, таких как C ++, с некоторыми существенными отличиями. См. Раздел руководства PHP по ссылкам .