PHP: Ссылки (указатели) на переменную. С примером реального применения.

Ссылка на переменную в php PHP

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

Выполнение выше приведенных строк интерпретатором PHP, на машинном(низком) уровне, это будет выглядеть примерно вот так:

Адрес ячейки Значение ячейки
aff123 1
aff124 abc
aff125 abc

Как видно из таблицы, все переменные в PHP являются неким подобием ассоциативного массива, где ключ — это  адрес ячейки, а значение — значение переменной.

Так вот ссылка на переменную — это и есть адрес ячейки памяти. Для взятие ссылки в PHP используется символ: ‘&’. Рассмотрим на примере:

Изначально может показаться, что это тоже самое что $b = $a, но на низком уровне, теперь будет такая таблица:

Адрес ячейки Значение ячейки
aff123 5
aff124 aff123

Теперь в нашей ячейки, куда мы передали ссылку, находиться не какое-либо значение, а адрес другой ячейки. И если мы обратимся к переменной, в которой содержится ссылка на другую переменную, то произойдёт в некотором смысле, redirect(перенаправление), на соответствующую переменную:

Ссылки в PHP могут образовывать бесконечную вложенность, например:

Точно так же можно ссылаться на элементы массива:

Или использовать их в цикле foreach для изменения значений исходного массива:

Мы можем осуществлять передачу по ссылке в функции:

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

Использование указателей на практике

В каких же случаях нам не обойтись без указателей? Представим такую задачу:

У нас есть строка:

Из неё нужно сформировать такой массив:

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

Конструкции типа:

мы использовать не можем, так как не знаем заранее количество вложенности. Соответственно вложенные цикл foreach мы тоже не можем использовать. Остается единственный вариант: попытаться сформировать подобный массив в одном цикле (не считая цикла перебора ключей строки). Сразу приведу готовый скрипт:

В строках 1-3, думаю все понятно, формируем наш массив ключей и одно итоговое значение, которое так же храниться в массиве. В 8-ой строке открываем цикл foreach для массива ключей, полученных из строки. Сразу проверяем, является ли переменная $result массивом, если нет то объявляем массив с ключом $val и в переменную $local_mass присваиваем ссылку на этот массив, для того что бы в дальнейшем мы могли через $local_mass менять значения в result.  Данное условие сработает в true только один раз, при первой итерации цикла. Все последующие итерации попадают в ветку else (основа нашего алгоритма). Здесь мы выполняем цикл foreach для переменной которая содержит ссылку на основной массив. В качестве значения $val2 так же берем ссылку. Внутри цикла объявляем ссылку $val2 в качестве массива и присваеваем соответственно ключ и значение. Так же обязательно перезаписываем переменную $local_mass на ссылку созданного массива. Таким образом получается, что при каждом обходе цикла($local_mass) мы формируем новую вложенность в исходном массиве $result. Ну а дальше всё просто, в переменную $last_index попадет последний ключ массива, а переменная $local_mass будет является этим массивом, куда мы и запишем итоговое значение. Результат выполнения данного кода:

Пишите в комментариях отзывы и вопросы, а так же делитесь своими результатами, если вы самостоятельно выполнили данную задачу.

Оцените статью