Что такое ссылки php

Содержание
  1. Ссылки в PHP
  2. Что такое ссылки
  3. Что делают ссылки
  4. Пример. Присвоение ссылок глобальным переменным внутри функции
  5. Пример. Ссылки и foreach
  6. Пример. Ссылки и сложные массивы
  7. Чем ссылки не являются
  8. Передача по ссылке
  9. Возвращение по ссылке
  10. Сброс переменных-ссылок
  11. Неявное использование механизма ссылок
  12. Ссылки global
  13. Что такое ссылки php
  14. Ссылки в PHP — как они работают и когда их использовать?
  15. Что же такое ссылки в PHP?
  16. Присвоение ссылки в PHP
  17. Удаление ссылки в PHP
  18. Передача переменных в функцию по ссылке
  19. Возвращение по ссылке из функций
  20. Изменение значений в предложении foreach с помощью ссылок в PHP
  21. Когда ссылки используются автоматически
  22. Ссылки в PHP при использовании ключевого слова global
  23. Ссылки в PHP, когда используется ключевое слово $this
  24. При передаче объектов
  25. Краткий обзор статьи о ссылках в PHP
  26. Читайте также
  27. Зачем в PHP ссылки?
  28. Объяснение ссылок
  29. Содержание
  30. User Contributed Notes 40 notes

Ссылки в PHP

Что такое ссылки

Что делают ссылки

Ссылки в PHP дают возможность двум переменным ссылаться на одно содержимое. Например:

Замечание: При копировании массива ссылок, они не разыменовываются. Это также касается массивов, передаваемых функциям по значению.

Такой же синтаксис можно использовать и в функциях, возвращая ссылки, а так же в операторе new (начиная с PHP 4.0.4):

Операция @, которая скрывает сообщения об ошибках, например в конструкторе @new, не может быть использована совместно с операцией & (&new). Это ограничение интерпретатора Zend.

Пример. Присвоение ссылок глобальным переменным внутри функции

Замечание: При использовании переменной-ссылки в foreach, изменяется содержание, на которое она ссылается.

Пример. Ссылки и foreach

Внимание: Сложные массивы в некоторых случаях могут копироваться вместо создания ссылок. например, следующий пример не будет работать как ожидалось.

Пример. Ссылки и сложные массивы

Чем ссылки не являются

Передача по ссылке

Любое другое выражение не должно передаваться по ссылке, так как результат не определён. Например, следующая передача по ссылке является неправильной:

Эти требования для PHP 4.0.4 и позже.

Возвращение по ссылке

Возвращение по ссылке используется в тех случаях, когда вы хотите использовать функцию для выбора переменной, с которой должна быть связана данная ссылка. При возвращении по ссылке используйте такой синтаксис:

В этом примере устанавливается свойство объекта, возвращённого функцией find_var, а не его копии, как было бы без использования ссылок.

Сброс переменных-ссылок

При сбросе ссылки, просто разрывается связь имени и содержимого переменной. Это не означает, что содержимое переменной будет разрушено. Например:

Опять же, можно провести аналогию с вызовом unlink (в Unix).

Неявное использование механизма ссылок

Многие синтаксические конструкции PHP реализованы через механизм ссылок, поэтому всё сказанное выше о ссылочном связывании применимо также и к этим конструкциям. Некоторые конструкции, вроде передающих и возвращающих по ссылке, рассмотрены ранее. Другие конструкции, использующие ссылки:

Ссылки global

Источник

Что такое ссылки php

Хотя в PHP нет такого понятия, как указатель, все же существует возможность создавать ссылки на другие переменные. Существует две разновидности ссылок: жесткие и символические (переменные переменные) (первые часто называют просто ссылками). Жесткие ссылки появились в PHP версии 4 (в третьей версии существовали лишь символические ссылки).

Жесткие ссылки в PHP

Жесткая ссылка представляет собой просто переменную, которая является синонимом другой переменной. Многоуровневые ссылки (то есть, ссылка на ссылку на переменную, как это можно делать, например, в Perl) не поддерживаются. Так что не стоит воспринимать жесткие ссылки серьезнее, чем синонимы.
Чтобы создать жесткую ссылку, нужно использовать оператор & (амперсанд). Например:

Ссылаться можно не только на переменные, но и на элементы массива (этим жесткие ссылки выгодно отличаются от символических). Например:

Впрочем, элемент массива, для которого планируется создать символическую ссылку, может и не существовать. Как в следующем случае:

В результате выполнения рассмотренного скрипта, хотя ссылке $b и не было ничего присвоено, в массиве $A создастся новый элемент с ключом c и значением — пустой строкой (мы можем это определить по результату работы echo). То есть, жесткая ссылка на самом деле не может ссылаться на несуществующий объект, а если делается такая попытка, то объект создается.

: Если убрать строку, в которой создается жесткая ссылка, то будет выведено сообщение о том, что элемент с ключом c не определен в массиве $A.

Жесткие ссылки удобно применять при передаче параметров пользовательской функции и возврате значения из нее.

Символические ссылки (переменные переменные)

— это всего лишь строковая переменная, хранящая имя другой переменной (переменная переменная). Чтобы добраться до значения переменной, на которую ссылается символическая ссылка, необходимо применить дополнительный знак $ перед именем ссылки. Рассмотрим пример:

Мы видим, что для того, чтобы использовать обычную строковую переменную как ссылку, нужно перед ней поставить еще один символ $.Это говорит интерпретатору, что надо взять не значение самой $p, а значение переменной, имя которой хранится в переменной $p.

Символические ссылки (переменные переменные) используюся достаточно редко.

Жесткие ссылки и пользовательские функции

Передача значений по ссылке

Вы можете передавать переменные в пользовательскую функцию по ссылке, если вы хотите разрешить функции модифицировать свои аргументы. В таком случае, пользовательския функция сможет изменять аргументы. Синтаксис таков:

Еще один интересный пример:

По ссылке можно передавать:


Переменные, например foo($a)

Оператор new, например foo(new foobar())

Ссылки, возвращаемые функцией, например:

Любое другое выражение не должно передаваться по ссылке, так как результат не определён. Например, следующая передача по ссылке является неправильной:

Возврат значений по ссылке

Возвращение по ссылке используется в тех случаях, когда вы хотите использовать функцию для выбора переменной, с которой должна быть связана данная ссылка. При возвращении по ссылке используйте такой синтаксис:

Еще один пример возврата значений пользовательской функции по ссылке:

Удаление ссылок (сброс ссылок)

При удалении ссылки, просто разрывается связь имени и содержимого переменной. Это не означает, что содержимое переменной будет разрушено. Например:

Этот код не сбросит $b, а только $a.

И все же, жесткая ссылка — не абсолютно точный синоним объекта, на который она ссылается. Дело в том, что оператор Unset(), выполненный для жесткой ссылки, не удаляет объект, на который она ссылается, а всего лишь разрывает связь между ссылкой и объектом.

Итак, жесткая ссылка и переменная (объект), на которую она ссылается, совершенно равноправны, но изменение одной влечет изменение другой. Оператор Unset() разрывает связь между объектом и ссылкой, но объект удаляется только тогда, когда на него никто уже не ссылается.

Опять же, можно провести аналогию с вызовом unlink (в Unix).

Источник

Ссылки в 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 передаёт ссылку на переменную, а не на значение переменной. Рассмотрим простой пример передачи по ссылке:

Таким образом, используйте передачу по ссылке всякий раз, когда вы хотите изменять переменную, которая передаётся в качестве аргумента функции. Просто не правда ли?! Кстати, не поддавайтесь искушению записать знак амперсанда перед аргументом при вызове функции:

Запись знака амперсанда перед параметром в определении функции является достаточным для того, чтобы передать переменную путем ссылки. Много функций, встроенных в PHP используют передачу аргументов по ссылке. Например, функция sort() принимает ссылку для сортировки массива, так что эта функция может изменить порядок элементов в массиве.

Возвращение по ссылке из функций

Если можно передавать переменные по ссылке в функцию, то так же можно возвращать ссылки из функции. Для этого нужно записать знак амперсанда перед названием функции в её определении. Вы также должны записать знак амперсанда (=&) при присвоении функции переменной, в противном случае вы просто присвоите значение, а не ссылку.

Возможно, вы не так часто пользуетесь возвращением по ссылке, как передачей по ссылке, но этот метод может быть полезен в некоторых ситуациях, например, когда вы хотите создать функцию поиска (или метод класса), которая находит переменную (или свойство класса) и возвращает ссылку на переменную или свойство, так чтобы вызываемый код мог управлять переменной или свойством.

Изменение значений в предложении foreach с помощью ссылок в PHP

Ещё один полезный пример использования ссылок для изменения значений в массиве с помощью цикла foreach. С помощью обычного циклаforeach, вы работаете скопией значений массива, так что, если вы измените её значения вы не затронете исходного массива. Например, попробуйте перевести в верхний регистр названия музыкальных групп в массиве с помощью цикла foreach:

Будет выведено следующее:

Как вы можете видеть, исходный массив не был изменён в результате работы цикла foreach. Вместе с тем, если мы ставим знак амперсанда до $band в операторе foreach $band становится ссылкой на исходный элемент массива, а не на его копию. Затем мы можем преобразовать элементы массива в верхний регистр:

Наш код теперь работает как и предполагалось, следующим образом:

Другой способ изменить значения массива в цикле является использование цикла for вместо foreach.

Когда ссылки используются автоматически

Итак, вы узнали четыре пути создания ссылки напрямую:

Кроме того, есть случаи, когда PHP автоматически создает ссылки. В большинстве случаев это вам не понадобится, но знать об этой возможности будет полезно!

Ссылки в PHP при использовании ключевого слова global

Не одно и то же, что следующий пример:

Ссылки в PHP, когда используется ключевое слово $this

При написании объектно-ориентированного кода часто используется ключевое слово $this. При использовании $this в пределах метода объекта, выполняется указание на текущий объект. Стоит запомнить, что $this всегда ссылается на объект, а не на его копию.

В примере приведенном выше $this — это ссылка на объект. Метод может изменять свойство объекта на новое значение в пределах этого объекта.

При передаче объектов

В отличие от других типов переменной, всякий раз, когда вы присваиваете, передаёте или возвращаете объект, вы возвращаете ссылку на объект, а не на его копию. Как правило, передавая функцию или метод вы работаете с самим объектом, а не с его копией.

В некоторых ситуациях, когда вы действительно хотите сделать копию объекта, вы можете использовать ключевое слово
clone. В сущности, всё намного тоньше. При создании переменной объекта, она содержит указатель на объект в памяти, а не на сам объект. При присвоении или передаче переменной вы на самом деле создаёте копию переменной. Но копия, также является просто указателем на объект — обе копии по-прежнему указывают на тот же объект. Таким образом, в большинстве случаев вы создаёте ссылки.

Краткий обзор статьи о ссылках в PHP

В этой статье были объяснены основы работы со ссылками в PHP. Вы изучили присвоение, передачу по ссылке, и возвращение по ссылке; научились использовать ссылки для изменения элементов массива в цикле foreach; и увидели ситуации, когда PHP создает ссылки автоматически.

Читайте также

Стандартные библиотеки PHP умеют генерировать только целые случайные числа. Однако, возникают задачи где нужно не целое рандомное число с максимально…

Казалось бы http_build_query — простая функция, однако, имеет некоторые особенности. Нельзя однозначно сказать что это баг, скорее просто недокументированная фича,…

Источник

Зачем в PHP ссылки?

709d157adacd4df151c992ad91098060

Модификация элементов внутри цикла требует ссылки:

Рекурсивное замыкание реализуется ссылкой:

Передача параметров в функцию по ссылке:

Можно продолжать. Я удивлен, как вы не столкнулись ни с одним из вышеперечисленного за год.

Это более предсказуемый код.

709d157adacd4df151c992ad91098060

ef6f089d60ce4842a101389f2bd126de

MintTea: Можно ещё придраться к фразе: «оно не относится к вопросу, т.к. при грамотном разграничении областей видимости проблемы с переиспользованием переменной просто не возникает» — просто в вопросе вообще ничего не было про грамотное разграничение областей видимости. Этот факт никак не влияет на то, относится замечание к вопросу или не относится. Какой-то другой факт — возможно, но не этот. Вопрос — про ссылки, ответ — про ссылки, комментарий — про ссылки.

Я просто думаю, что если бы любой человек, который советует делать foreach в ссылку, упоминал бы и меры предосторожности, меньше людей вляпывались бы в ситуацию, когда последний элемент массива ведёт себя неадекватно тому, что они от него ждали.

Это не про подход к программированию, это про подход к обучению и раздаче советов новичкам.

709d157adacd4df151c992ad91098060

fd0900ac42144fd5a6bed2f7663de1df

60b92a67e11bd782010237

Мы обычно используем ссылки, чтобы вернуть из функции «несколько» результатов. Лучше один раз увидеть. Предположим, мы пишем функцию для запроса данных к БД. Начнем с простого:

Вызов:
print_r ( query(«Select * from test» ) );

60b92a67e11bd782010237

Я думаю, что механизм ссылок самым непосредственным образом помогает вам работать с БД. Но, так как ядро PHP само занимается оптимизациями, связанными со ссылками, от кодера не очень часто требуется их использовать явно.

Это тоже самое, что жёсткие ссылки в файловой системе. От них может быть большая польза, но рядовой пользователь не очень часто их использует осознанно.

Источник

Объяснение ссылок

Содержание

User Contributed Notes 40 notes

A little gotcha (be careful with references!):

Add ‘unset($a)’ between the foreachs to obtain the ‘correct’ output:

On the post that says php4 automagically makes references, this appears to *not* apply to objects:

If you want to know the reference count of a particular variable, then here’s a function that makes use of debug_zval_dump() to do so:

It’s also even more confusing when dealing with variables that have been assigned by reference (=&), either on the right or left side of the assignment, so for that reason, the above function doesn’t really work for those sorts of variables. I’d use it more on object instances.

However, even taking into account that passing a variable to a function adds one to the reference count; which should mean that calling refcount() adds one, and then calling debug_zval_dump() adds another, refcount() seems to have aquired another reference from somewhere; hence subtracting 3 instead of 2 in the return line. Not quite sure where that comes from.

I’ve only tested this on 5.3; due to the nature of debug_zval_dump(), the results may be completely different on other versions.

Here is a good magazine article (PDF format) that explains the internals of PHP’s reference mechanism in detail: http://derickrethans.nl/files/phparch-php-variables-article.pdf

It should explain some of the odd behavior PHP sometimes seems to exhibit, as well as why you can’t create «references to references» (unlike in C++), and why you should never attempt to use references to speed up passing of large strings or arrays (it will make no difference, or it will slow things down).

It was written for PHP 4 but it still applies. The only difference is in how PHP 5 handles objects: passing object variables by value only copies an internal pointer to the object. Objects in PHP 5 are only ever duplicated if you explicitly use the clone keyword.

in addition to what ‘jw at jwscripts dot com’ wrote about unset; it can also be used to «detach» the variable alias so that it may work on a unique piece of memory again.

// detach pretty, but slower
eval( detach ( ‘$v2’ ));

after:
v1=shared?
v2=shared no more
v3=shared still
v4=shared still
>

http://www.obdev.at/developers/articles/00002.html says there’s no such thing as an «object reference» in PHP, but with detaching it becomes possible.

Hopefully detach, or something like it, will become a language construct in the future.

This is discussed before (below) but bears repeating:

$a = null; ($a =& null; does not parse) is NOT the same as unset($a);

Moral: use unset when it is called for.

Simply put, here’s an example of what referencing IS:

I found a very useful summary of how references work in PHP4 (and some of the common pitfalls) in this article: http://www.obdev.at/developers/articles/00002.html

It deals with some subtle situations and I recommend it to anyone having difficulty with their references.

in the example below, you would get the same result if you change the function to something like:

Re-using variables which where references before, without unsetting them first, leads to unexpected behaviour.

The following code:

Applying unset($index) before re-using the variable fixes this and the expected list will be produced:
1
2
3

You should have in mind that php4 keep assigned variables «automagically» referenced until they are overwritten. So the variable copy is not executed on assignment, but on modification. Say you have this:

Don’t use references in function parameters to speed up aplications, because this is automatically done. I think that this should be in the manual, because it can lead to confusion.

I don’t know if this is a bug (I’m using PHP 5.01) but you should be careful when using references on arrays.
I had a for-loop that was incredibly slow and it took me some time to find out that most of the time was wasted with the function sizeof() at every loop, and even more time I spent finding out that this problem it must be somehow related to the fact, that I used a reference of the array. Take a look at the following example:

I ran into a bit of a problem recently, with an array copy resulting in a reference copy of one of the elements instead of a clone. Sample code:

«Due to peculiarities of the internal workings of PHP, if a reference is made to a single element of an array and then the array is copied, whether by assignment or when passed by value in a function call, the reference is copied as part of the array. This means that changes to any such elements in either array will be duplicated in the other array (and in the other references), even if the arrays have different scopes (e.g. one is an argument inside a function and the other is global)! Elements that did not have references at the time of the copy, as well as references assigned to those other elements after the copy of the array, will behave normally (i.e. independent of the other array).»

However, this paragraph appears to have been removed from this page at some point, presumably because it was a bit obscure. The comments section seem to be a proper place for this, though.

This is not the case. In fact, a C pointer version of this example (shown below) would behave exactly the same way (it would not modify what bar references) as the PHP reference version.

In this case, just as in the case of PHP references, the call foo(bar) doesn’t change what bar references. If you wanted to change what bar references, then you would need to work with a double pointer like so:

It seems like PHP has problems with references, like that it can’t work properly with circular references or free properly structure with more references. See http://bugs.php.net/?id=30053.

I have big problem with this and I hope someone from PHP add proper warning with explanation IN manual, if they can’t fix it.

(v5.1.4)
One cool thing about var_dump is it shows which variables are references (when dumping arrays), symbolized by ‘∫’ for int/null, and by ‘&’ for boolean/double/string/array/object. I don’t know why the difference in symmmmbolism.
After playing around I found a better way to implement detaching (twas by accident). var_dump can show what’s going on.

Use this when you know a variable is a reference, and you want to assign a new value without effecting other vars referencing that piece of memory. You can initialize it with a new constant value, or variable, or new reference all in once step.

Responding to post from nathan (who was responding to iryoku).

What it does internally is a totally different story. I’ve tested «copying» an object which contains a 200,000 element array, it takes almost no time at all until you finally change something in one of the copies, because internally it only makes the copy when it becomes necessary. The original assignment takes less than a millisecond, but when I alter one of the copies, it takes something like a quarter of a second. But this only happens if I alter the 200,000 element array, if I alter a single integer of the object, it takes less than a microsecond again, so the interpretter seems to be smart enough to make copies of some of the objects variables and not others.

The result is that when you change a function to pass by reference, it will only become more efficient if, inside the function, the passed variable is having its data altered, in which case passing by reference causes your code to alter the data of the original copy. If you are passing an object and calling a function in that object, that function may alter the object without you even knowing, which means that you should pass an object by reference as long as it is ok for the original copy to be effected by what you do with the object inside the function.

I think the real moral of the story is this:
1) Pass by reference anything that should refer to and affect the original copy.
2) Pass not by reference things that will definitely not be altered in the function (for an object, it may be impossible to know whether it alters itself upon calling one of its functions).
3) If something needs to be altered inside a function without effecting the original copy, pass it not by reference, and pass the smallest practical part that needs to change, rather than passing, for example, a huge array of which one little integer will be altered.

Or a shorter version: Only pass things by reference when you need to refer to the original copy! (And don’t pass huge arrays or long strings when you need to change just a small part of them!)

//above was Noted By Dave at SymmetricDesign dot com//
//and below is my opinion to this simple problem. //

This is an normal referencing problem.

if there’s some problems in my notes, plz, note that on above.

Источник

Моя дача
Adblock
detector