📚
#47 04.10.2025 PHP Basics

Расскажите об использовании символа & (амперсанд).

Символ & в PHP создает ссылки на переменные ($b = &$a). Используется для передачи/возврата по ссылке в функциях, побитовых операций (&, &=), и модификации элементов в foreach. Всегда делайте unset() после циклов со ссылками.

Подробнее
⚠️
Внимание! Этот текст был сгенерирован AI-ассистентом. Информация может содержать неточности и требует проверки.

Полный ответ:

1. Ссылки (References)

Это основное и самое важное использование &.

Присваивание по ссылке:

$a = 10;
$b = &$a; // $b - ссылка на $a

$b = 20;
echo $a; // 20 (изменилось через ссылку $b)

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

function increment(&$value) {
    $value++;
}

$number = 5;
increment($number);
echo $number; // 6 (оригинал изменен)

Возврат ссылки из функции:

class ValueHolder {
    private $value;
    
    public function &getValue() {
        return $this->value;
    }
}

$obj = new ValueHolder();
$reference = &$obj->getValue();
$reference = 100; // Изменяет приватное свойство

2. Побитовое И (Bitwise AND)

& используется для побитовых операций.

$a = 5;    // 0101 в двоичной
$b = 3;    // 0011 в двоичной
$result = $a & $b; // 0001 (1 в десятичной)

echo $result; // 1

3. Комбинированные операторы присваивания

&= — побитовое И с присваиванием.

$flags = 7;     // 0111
$mask = 3;      // 0011
$flags &= $mask; // 0011 (3)
// Эквивалентно: $flags = $flags & $mask;

4. Ссылки в массивах и циклах

Ссылки на элементы массива:

$array = [1, 2, 3];
foreach ($array as &$value) {
    $value *= 2; // Изменяем оригинальные элементы
}
unset($value); // Важно! Разрываем ссылку
print_r($array); // [2, 4, 6]

Опасность висячих ссылок:

$array = [1, 2, 3];
foreach ($array as &$value) {}
$value = 100; // Изменяет последний элемент массива!
print_r($array); // [1, 2, 100]

5. Ссылки в функциях массива

Некоторые функции работают со ссылками на элементы.

$array = [1, 2, 3];
array_walk($array, function(&$value, $key) {
    $value *= 2;
});
print_r($array); // [2, 4, 6]

6. Оператор ссылки в объявлениях

В функциях:

// Параметр по ссылке
function process(&$data) {
    $data['processed'] = true;
}

$input = ['name' => 'test'];
process($input);
print_r($input); // Добавлен 'processed' => true

В методах:

class Collection {
    private $items = [];
    
    public function addItem(&$item) {
        $this->items[] = &$item;
    }
}

7. Отличие от указателей в C/C++

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

8. Лучшие практики и предупреждения

Всегда делайте unset() после циклов:

$data = [1, 2, 3];
foreach ($data as &$value) {
    // работа
}
unset($value); // Защита от случайного изменения

Избегайте ненужных ссылок:

// Плохо (ненужная сложность)
function calculate(&$a, &$b) {
    return $a + $b;
}

// Хорошо
function calculate($a, $b) {
    return $a + $b;
}

Используйте для модификации больших массивов:

// Эффективно по памяти
function processLargeArray(&$array) {
    foreach ($array as &$item) {
        $item = strtoupper($item);
    }
    unset($item);
}

9. Особенности производительности

Миф: “Ссылки всегда быстрее”. Реальность: В современном PHP (Zend Engine 3) Copy-On-Write делает разницу незначительной. Используйте ссылки для семантики, а не оптимизации.

10. Обработка ошибок

// Нельзя создать ссылку на несуществующую переменную
$ref = &$undefined; // Notice + NULL

// Нельзя создать ссылку на результат выражения
$ref = &(2 + 2); // Parse error

Итог:

Амперсанд & в PHP имеет несколько фундаментальных ролей:

  1. Ссылки — создание псевдонимов переменных ($b = &$a)
  2. Побитовое И — битовые операции ($a & $b)
  3. Передача по ссылке в функциях (function foo(&$param))
  4. Работа с элементами массивов в циклах (foreach ($array as &$value))

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