Как работает ссылка на переменную php
Unlike in C, PHP references are not treated as pre-dereferenced pointers, but as complete aliases.
The data that they are aliasing («referencing») will not become available for garbage collection until all references to it have been removed.
«Regular» variables are themselves considered references, and are not treated differently from variables assigned using =& for the purposes of garbage collection.
The following examples are provided for clarification.
1) When treated as a variable containing a value, references behave as expected. However, they are in fact objects that *reference* the original data.
var = «foo» ;
$ref1 =& $var ; // new object that references $var
$ref2 =& $ref1 ; // references $var directly, not $ref1.
echo $ref1 ; // >Notice: Undefined variable: ref1
echo $ref2 ; // >foo
echo $var ; // >foo
?>
2) When accessed via reference, the original data will not be removed until *all* references to it have been removed. This includes both references and «regular» variables assigned without the & operator, and there are no distinctions made between the two for the purpose of garbage collection.
echo $var ; // >Notice: Undefined variable: var
echo $ref ; // >foo
?>
3) To remove the original data without removing all references to it, simply set it to null.
echo $var ; // Value is NULL, so nothing prints
echo $ref ; // Value is NULL, so nothing prints
?>
4) Placing data in an array also counts as adding one more reference to it, for the purposes of garbage collection.
Ссылки — Основы PHP
В этом уроке мы изучим ссылки. Эта тема немного своеобразная: механизм ссылок напрямую используется редко.
Но это все равно важная тема. Когда мы начнем использовать массивы и объекты, нам понадобится понимание того, как ссылки работают.
Не относитесь к этому материалу слишком серьезно. Главное — уловить концепцию и знать само понятие, все остальное по необходимости.
Ссылки в PHP — это средство доступа к содержимому одной переменной под разными именами.
Так работает доступ без ссылок:
$a = 5; $b = $a; $a = 3; echo $b; // => 5
А теперь попробуем использовать ссылки:
$a = 5; $b =& $a; $a = 3; echo $b; // => 3
Запись =& говорит, что переменная слева начинает указывать на те же данные, что и переменная в правой части выражения.
Здесь стоит сказать: если вы запомнили переменные как коробочки, которые содержат внутри себя данные, то это не совсем верная аналогия. На самом деле, данные хранятся отдельно, а переменные — отдельно. Поэтому правильно говорить, что переменные ссылаются на свои данные.
Рассмотрим первую ситуацию подробнее:
$a = 5; $b = $a;
В этом коде переменная $a связывается с числом 5 . Затем мы выполняем присвоение $b = $a . Несмотря на то, что справа стоит $a , правильно этот код воспринимать как $b = 5 . Другими словами, вместо $a подставляется ее значение, которое становится значением $b .
Эти переменные не имеют между собой ничего общего, они не ссылаются на одни и те же данные. Это может показаться странным, ведь и там, и там записано одно и то же. Но это не так — у каждой переменной своя собственная пятерка.
Но все меняется если во время присвоения добавить амперсанд: $b =& $a . Теперь $b и $a ссылаются на одно и то же значение. Если поменять его в $b , то оно поменяется и для $a . Обратное тоже верно. $a и $b здесь абсолютно эквивалентны, но это не означает, что $a указывает на $b , или наоборот. Это означает, что $a и $b указывают на одно и то же значение.
Вероятно, сейчас вы чувствуете легкое замешательство. Если это так — не переживайте, это нормально. Тема ссылок — вещь, которую сложно понять и прочувствовать, прочитав один урок.
Есть три основных операции с использованием ссылок:
- Присвоение по ссылке
- Передача по ссылке
- Возврат по ссылке
Выше мы рассматривали довольно искусственные примеры. Практически единственное место, где ссылки встречаются в реальной жизни — аргументы функций, причем встроенные в сам язык. В основном это касается массивов, с которыми мы познакомимся позже. А пока посмотрим на этот прием без них:
// Либо так: function strangeFunction(&$text) function strangeFunction(string &$text) $text = 'hei'; > $text = 'money'; strangeFunction($text); echo $text; // => hei
В этом примере сама функция декларирует, что ее аргумент передается по ссылке. Самое неприятное — вы об этом даже не узнаете, если внимательно не прочитаете документацию. Обычно такие функции ничего не возвращают, они меняют аргументы, что, кстати, считается плохой практикой. Подобное поведение имеет смысл только в некоторых ситуациях, где крайне важна производительность — например, при сортировке массивов.
Особняком стоят объекты, которые всегда передаются по ссылке. Об этом рассказывается в следующих курсах.
Дополнительные материалы
- Официальная документация
- Пример функции работающей со ссылками: fscan
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Как работает ссылка на переменную php
points to post below me.
When you’re doing the references with loops, you need to unset($var).
19 years ago
In reply to lars at riisgaardribe dot dk,
When a variable is copied, a reference is used internally until the copy is modified. Therefore you shouldn’t use references at all in your situation as it doesn’t save any memory usage and increases the chance of logic bugs, as you discoved.
13 years ago
I think a correction to my last post is in order.
When there is a constructor, the strange behavior mentioned in my last post doesn’t occur. My guess is that php was treating reftest() as a constructor (maybe because it was the first function?) and running it upon instantiation.
class reftest
public $a = 1 ;
public $c = 1 ;
public function __construct ()
return 0 ;
>
$reference = new reftest ();
$reference -> reftest ();
$reference -> reftest2 ();
echo $reference -> a ; //Echoes 2.
echo $reference -> c ; //Echoes 2.
?>
12 years ago
In this example class name is different from its first function and however there is no construction function. In the end as you guess «a» and «c» are equal. So if there is no construction function at same time class and its first function names are the same, «a» and «c» doesn’t equal forever. In my opinion php doesn’t seek any function for the construction as long as their names differ from each others.
class reftest_new
<
public $a = 1 ;
public $c = 1 ;
$reference = new reftest_new ();
$reference -> reftest ();
$reference -> reftest2 ();
echo $reference -> a ; //Echoes 2.
echo $reference -> c ; //Echoes 2.
?>
2 years ago
It matters if you are playing with a reference or with a value
Here we are working with values so working on a reference updates original variable too;
$b = & $a;
echo «$a, $b»; //Output: 1, 1
$b++;
echo «$a, $b»;//Output: 2, 2 both values are updated
$b = 10;
echo «$a, $b»;//Output: 10, 10 both values are updated
$b =$c; //This assigns value 2 to $b which also updates $a
echo «$a, $b»;//Output: 22, 22
But, if instead of $b=$c you do
$b = &$c; //Only value of $b is updated, $a still points to 10, $b serves now reference to variable $c
echo «$a, $b»//Output: 10, 22
15 years ago
The order in which you reference your variables matters.
echo $a1 ; //Echoes «One»
echo $b1 ; //Echoes «One»
echo $a2 ; //Echoes «Four»
echo $b2 ; //Echoes «Four»
?>
15 years ago
If you set a variable before passing it to a function that takes a variable as a reference, it is much harder (if not impossible) to edit the variable within the function.
foo ( $unset );
echo( $unset );
foo ( $set = «set\n» );
echo( $set );
It baffles me, but there you have it.
15 years ago
In reply to Drewseph using foo($a = ‘set’); where $a is a reference formal parameter.
$a = ‘set’ is an expression. Expressions cannot be passed by reference, don’t you just hate that, I do. If you turn on error reporting for E_NOTICE, you will be told about it.
Resolution: $a = ‘set’; foo($a); this does what you want.
16 years ago
Here’s a good little example of referencing. It was the best way for me to understand, hopefully it can help others.
13 years ago
When using references in a class, you can reference $this-> variables.
class reftest
public $a = 1 ;
public $c = 1 ;
$reference = new reftest ();
$reference -> reftest ();
$reference -> reftest2 ();
echo $reference -> a ; //Echoes 2.
echo $reference -> c ; //Echoes 2.
?>
However, this doesn’t appear to be completely trustworthy. In some cases, it can act strangely.
class reftest
public $a = 1 ;
public $c = 1 ;
$reference = new reftest ();
$reference -> reftest ();
$reference -> reftest2 ();
echo $reference -> a ; //Echoes 3.
echo $reference -> c ; //Echoes 2.
?>
In this second code block, I’ve changed reftest() so that $b increments instead of just gets changed to 2. Somehow, it winds up equaling 3 instead of 2 as it should.
16 years ago
I discovered something today using references in a foreach
echo $a1 [ ‘a’ ]; // will echo x
foreach ( $a2 as $k => $v )
<>
echo $a1 [ ‘a’ ]; // will echo b (!)
?>
After reading the manual this looks like it is meant to happen. But it confused me for a few days!
(The solution I used was to turn the second foreach into a reference too)
14 years ago
An interesting if offbeat use for references: Creating an array with an arbitrary number of dimensions.
For example, a function that takes the result set from a database and produces a multidimensional array keyed according to one (or more) columns, which might be useful if you want your result set to be accessible in a hierarchial manner, or even if you just want your results keyed by the values of each row’s primary/unique key fields.
function array_key_by ( $data , $keys , $dupl = false )
/*
* $data — Multidimensional array to be keyed
* $keys — List containing the index/key(s) to use.
* $dupl — How to handle rows containing the same values. TRUE stores it as an Array, FALSE overwrites the previous row.
*
* Returns a multidimensional array indexed by $keys, or NULL if error.
* The number of dimensions is equal to the number of $keys provided (+1 if $dupl=TRUE).
*/
// Sanity check
if (! is_array ( $data )) return null ;
// Allow passing single key as a scalar
if ( is_string ( $keys ) or is_integer ( $keys )) $keys = Array( $keys );
elseif (! is_array ( $keys )) return null ;
// Our output array
$out = Array();
// Loop through each row of our input $data
foreach( $data as $cx => $row ) if ( is_array ( $row ))
// Loop through our $keys
foreach( $keys as $key )
$value = $row [ $key ];
if (!isset( $last )) // First $key only
if (!isset( $out [ $value ])) $out [ $value ] = Array();
$last =& $out ; // Bind $last to $out
>
else // Second and subsequent $key.
if (!isset( $last [ $value ])) $last [ $value ] = Array();
>
if (isset( $last ))
// At this point, copy the $row into our output array
if ( $dupl ) $last [ $cx ] = $row ; // Keep previous
else $last = $row ; // Overwrite previous
>
unset( $last ); // Break the reference
>
else return NULL ;
// A sample result set to test the function with
$data = Array(Array( ‘name’ => ‘row 1’ , ‘foo’ => ‘foo_a’ , ‘bar’ => ‘bar_a’ , ‘baz’ => ‘baz_a’ ),
Array( ‘name’ => ‘row 2’ , ‘foo’ => ‘foo_a’ , ‘bar’ => ‘bar_a’ , ‘baz’ => ‘baz_b’ ),
Array( ‘name’ => ‘row 3’ , ‘foo’ => ‘foo_a’ , ‘bar’ => ‘bar_b’ , ‘baz’ => ‘baz_c’ ),
Array( ‘name’ => ‘row 4’ , ‘foo’ => ‘foo_b’ , ‘bar’ => ‘bar_c’ , ‘baz’ => ‘baz_d’ )
);
// First, let’s key it by one column (result: two-dimensional array)
print_r ( array_key_by ( $data , ‘baz’ ));
// Or, key it by two columns (result: 3-dimensional array)
print_r ( array_key_by ( $data , Array( ‘baz’ , ‘bar’ )));
// We could also key it by three columns (result: 4-dimensional array)
print_r ( array_key_by ( $data , Array( ‘baz’ , ‘bar’ , ‘foo’ )));
Ссылки в PHP — как они работают и когда их использовать?
Доброго времени суток, уважаемые читатели блога SoftMaker.kz. На этом сайте уже есть статья о том что такое PHP . А сегодня мы поговорим, о ссылках в языке программирование PHP, так как ссылки являются весьма полезной частью языка программирования PHP. Это утверждение касается так же и большинства других языков программирования. Тем не менее, тема ссылок может быть не вполне понятной при первом знакомстве с ней.
Эта статья поможет устранить всё, что может быть непонятно при первом знакомстве с темой ссылок в PHP . Вы узнаете, что такое ссылки в PHP и как они работают. Также в этой статье вы узнаете, как создавать и удалять ссылки, а также как передавать и возвращать переменную по ссылке в функцию и из неё. Вы также изучите некоторые другие виды ссылок, и узнаете о ситуациях, когда PHP создаёт ссылки автоматически.
Что же такое ссылки в PHP?
Ссылка — это способ обратиться к переменной с помощью другого имени. PHP-ссылки не похожи на указатели языка программирования C и не являются псевдонимами таблицы символов. Во многих отношениях они похожи на ярлык в Windows, файл псевдоним в Mac OS X и символические ссылки в Linux.
Присвоение ссылки в PHP
Здесь мы создали переменную $myVar со значением «Привет!». Затем мы присвоили значение другой переменной $anotherVar. Это копия значения первой переменной во вторую. Затем мы изменим значение, сохраненное в $anotherVar на «Увидимся позже».
Поскольку две переменные являются независимыми, $myVar по-прежнему сохраняет свою первоначальное значение ( «Привет!» ), которое будет выедено на странице. Пока всё идёт хорошо. А теперь давайте изменим пример, чтобы присвоить переменной $myVar значение $anotherVar, используя ссылку, а не значение. Чтобы сделать это, мы просто напишем знак амперсанда («&» ) после знака равенства :
Теперь вы можете видеть, что $myVar также изменен на «Увидимся позже»! Почему это произошло? Вместо того, чтобы присвоить значение переменной $myVar переменной $anotherVar — которые просто создают две независимых копии одного и того же значения — мы сделали переменную $anotherVar ссылкой на значение $myVar. Другими словами, $myVar и $anotherVarоба указывают на одно и то же значение. Таким образом, когда мы присвоили новое значение переменной, $anotherVarзначение переменной $myVar также изменилось.
Обратите внимание на то, что мы могли бы изменить значение переменной $myVar на «Увидимся позже» вместо изменения переменной $anotherVar и результат был бы точно такой же. Две переменных, по сути, являются идентичными.
Удаление ссылки в PHP
Вы можете удалить ссылку с помощью функции PHP unset() также как вы удаляете обычную переменную. Когда вы удаляете ссылку, вы просто удаляете саму ссылку, а не значение ссылки:
Значение остается в памяти, пока вы не удалите все ссылки на него, в том числе в исходной переменной:
Передача переменных в функцию по ссылке
Ссылки действительно работают, если вы передаёте их как аргументы функций. Как правило, когда вы передаете переменную в функцию,
функция получает копию значения этой переменной. Передавая ссылку на переменную функция может сослаться на эту переменную,
но что еще важнее, изменить исходную переменную.
Чтобы передать аргумент в качестве ссылки установите знак амперсанда перед именем параметра функции:
Теперь, каждый раз при вызове myFunc() и передаче переменной PHP передаёт ссылку на переменную, а не на значение переменной. Рассмотрим простой пример передачи по ссылке:
goodbye( $myVar); echo $myVar; // Выведет «Увидимся позже»
Здесь мы создали функцию goodbye() , которая принимает ссылку на переменную. Ссылка хранится в параметре $greeting. Функция присваивает новое значение («Увидимся позже») переменной $greeting, которая изменяет значение сохранённое в переменной, которая была передана в функцию.
Мы это проверим, путем создания переменной $myVar, с первоначальным значением «Привет!», вызвав функцию goodbye() с параметром $myVar , переданным по ссылке. Функция goodbye( изменяет значение, сохраненное в $myVar на «Увидимся позже».
Таким образом, используйте передачу по ссылке всякий раз, когда вы хотите изменять переменную, которая передаётся в качестве аргумента функции. Просто не правда ли?! Кстати, не поддавайтесь искушению записать знак амперсанда перед аргументом при вызове функции:
Запись знака амперсанда перед параметром в определении функции является достаточным для того, чтобы передать переменную путем ссылки. Много функций, встроенных в PHP используют передачу аргументов по ссылке. Например, функция sort() принимает ссылку для сортировки массива, так что эта функция может изменить порядок элементов в массиве.
Возвращение по ссылке из функций
Если можно передавать переменные по ссылке в функцию, то так же можно возвращать ссылки из функции. Для этого нужно записать знак амперсанда перед названием функции в её определении. Вы также должны записать знак амперсанда (=&) при присвоении функции переменной, в противном случае вы просто присвоите значение, а не ссылку.
$Numwidgetsref =& getNumWidgets( ); $Numwidgetsref--; echo " \ $numWidgets = $numWidgets
"; // Выведет " 9 ". echo " \ $numWidgetsRef = $numWidgetsRef
"; // выводит " 9 ". ?>
В этом примере функция getNumWidgets() находит глобальную переменную $numWidgets и возвращает ссылку на неё. Затем мы вызываем getNumWidgets() , которая сохраняет возвращенные ссылки в $numWidgetsRef, и уменьшает значение в переменной, на которую указывает $numWidgetsRef. Это то же самое значение, на которое указывает переменная $numWidgets, как можно увидеть из результата работы функции echo.
Возможно, вы не так часто пользуетесь возвращением по ссылке, как передачей по ссылке, но этот метод может быть полезен в некоторых ситуациях, например, когда вы хотите создать функцию поиска (или метод класса), которая находит переменную (или свойство класса) и возвращает ссылку на переменную или свойство, так чтобы вызываемый код мог управлять переменной или свойством.
Изменение значений в предложении foreach с помощью ссылок в PHP
Ещё один полезный пример использования ссылок для изменения значений в массиве с помощью цикла foreach. С помощью обычного циклаforeach, вы работаете скопией значений массива, так что, если вы измените её значения вы не затронете исходного массива. Например, попробуйте перевести в верхний регистр названия музыкальных групп в массиве с помощью цикла foreach:
echo ""; Print_r( $bands); echo " < /pre>"; ?>Будет выведено следующее:
The Who [1] => The Beatles [2] => The Rolling Stones) ?>Как вы можете видеть, исходный массив не был изменён в результате работы цикла foreach. Вместе с тем, если мы ставим знак амперсанда до $band в операторе foreach $band становится ссылкой на исходный элемент массива, а не на его копию. Затем мы можем преобразовать элементы массива в верхний регистр:
echo ""; Print_r( $bands); echo " < /pre>"; ?>Наш код теперь работает как и предполагалось, следующим образом:
THE WHO [1] => THE BEATLES [2] => THE ROLLING STONES) ?>Другой способ изменить значения массива в цикле является использование цикла for вместо foreach.
Когда ссылки используются автоматически
Итак, вы узнали четыре пути создания ссылки напрямую:
- Присваивание ссылки
- Передача по ссылке
- Возвращение по ссылке
- Создание ссылки в цикле foreach
Кроме того, есть случаи, когда PHP автоматически создает ссылки. В большинстве случаев это вам не понадобится, но знать об этой возможности будет полезно!
Ссылки в PHP при использовании ключевого слова global
Когда вы используете ключевое слово global внутри функции, чтобы иметь доступ к глобальной переменной, тогда, на самом деле, вы создаёте ссылку в глобальной переменной массива $GLOBALS.
Не одно и то же, что следующий пример:
Ссылки в PHP, когда используется ключевое слово $this
При написании объектно-ориентированного кода часто используется ключевое слово $this. При использовании $this в пределах метода объекта, выполняется указание на текущий объект. Стоит запомнить, что $this всегда ссылается на объект, а не на его копию.
aProperty = 456; // $это ссылка на объект > > $myObject = new MyClass(); $myObject->aMethod(); echo $myObject->aProperty; // Выведет "456" ?>
В примере приведенном выше $this — это ссылка на объект. Метод может изменять свойство объекта на новое значение в пределах этого объекта.
При передаче объектов
В отличие от других типов переменной, всякий раз, когда вы присваиваете, передаёте или возвращаете объект, вы возвращаете ссылку на объект, а не на его копию. Как правило, передавая функцию или метод вы работаете с самим объектом, а не с его копией.
$myObject = new MyClass(); $Yourobject = $myObject; // $yourObject и $myObject указывают на тот же объект ?>
В некоторых ситуациях, когда вы действительно хотите сделать копию объекта, вы можете использовать ключевое слово
clone. В сущности, всё намного тоньше. При создании переменной объекта, она содержит указатель на объект в памяти, а не на сам объект. При присвоении или передаче переменной вы на самом деле создаёте копию переменной. Но копия, также является просто указателем на объект — обе копии по-прежнему указывают на тот же объект. Таким образом, в большинстве случаев вы создаёте ссылки.
Краткий обзор статьи о ссылках в PHP
В этой статье были объяснены основы работы со ссылками в PHP. Вы изучили присвоение, передачу по ссылке, и возвращение по ссылке; научились использовать ссылки для изменения элементов массива в цикле foreach; и увидели ситуации, когда PHP создает ссылки автоматически.
Post Views: 4 239
Читайте также
Cлучайные числа с плавающей точкой в PHP Стандартные библиотеки PHP умеют генерировать только целые случайные числа. Однако, возникают задачи где нужно не целое рандомное число с максимально…
Особенности http_build_query в PHP Казалось бы http_build_query — простая функция, однако, имеет некоторые особенности. Нельзя однозначно сказать что это баг, скорее просто недокументированная фича,…
Как установить библиотеку ncurses для PHP yum install ncurses-devel phpize --clean phpize ./configure (./configure --with-php-config=/usr/bin/php-config --enable-ncursesw=autodetect --with-ncurses) make make install ls /usr/lib/php/modules/ncurses.so nano /etc/php.d/ncurses.ini extension=ncurses.so php…
