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

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 будет является этим массивом, куда мы и запишем итоговое значение. Результат выполнения данного кода:

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

Похожие записи
  • PHP обработка исключения
  • PHP: ассоциативный массив
Комментарии

$str = «app.ext.list.a101 = from-context»;

list($keys, $value) = explode(» = «, $str); $keys = array_reverse(explode(‘.’, $keys));

foreach($keys as $key)

Ссылки != Указатели Прочтите наконец документацию PHP P.S Либо перепишите статью нормально, либо не пудрите мозги людям PHP != C++

«Ссылки, так же их иногда называют указатели» — После этих слов перестал читать статью… Вы совершенно не разбираетесь в публикуемой теме. Статья ради статьи? Зачем морочить голову людям?

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

15 минут вместе с прочтением статьи не особенно углубляясь в каноны оптимального кода (без ссылок и указателей )))):

$str = «app.ext.list.a101 = from-context»;

$arr = array(); foreach ($keys as $value)

Кстати, неплохо было бы добавить поддержку MD в комментариях, иначе код так отстойно выглядит, что жалеешь, что написал. )))

Статья про ссылки, логично и пример решения задачи создать со ссылками: $str = «app.ext.list.a101 = from-context»; list($keys, $value) = explode(» = «, $str); $keys = explode(«.», $keys); $val = array(); $result = array();

$result = &$tmp; foreach($keys as $key) $last = $value; var_dump($result);

Здравствуйте! Помогите пожалуйста разобраться с методом Tommy Lacroix tree(многоуровневое меню)? Таблица базы данных: ( id , title , parent ) (685, ‘Комплектующие к Apple’, 0) (691, ‘Запчасти iPad’, 685) (692, ‘Запчасти iPhone’, 685) (693, ‘Запчасти iPod’, 685) (694, ‘Запчасти Mac’, 685) (695, ‘iPad’, 691) (696, ‘iPad 2’, 691) (697, ‘iPad NEW (iPad 3)’, 691) (698, ‘iPad 4’, 691) (699, ‘iPad mini’, 691) (700, ‘iPhone’, 692) (701, ‘iPhone 3G/3GS’, 692) (702, ‘iPhone 4’, 692) (703, ‘iPhone 4S’, 692) (704, ‘iPhone 5’, 692) (705, ‘Микросхемы Apple’, 685).

Сам метод: function getTree($dataset) Возвращает $tree, но ведь в else не написано $tree. Каким образом, в таком случае, из else данные попадают в $tree?

📎📎📎📎📎📎📎📎📎📎