В чем разница между передачей данных по ссылке и по значению в PHP?

Ответ

Механизм передачи определяет, работает ли функция с копией данных или с оригиналом.

Передача по значению — значение переменной копируется. Изменения внутри функции не затрагивают оригинальную переменную.

function incrementByValue($num) {
    $num += 10;
    return $num;
}

$original = 5;
$result = incrementByValue($original);

echo $original; // 5 (не изменилась)
echo $result;   // 15

Передача по ссылке — в функцию передается ссылка на оригинальную переменную (с помощью &). Изменения внутри функции влияют на оригинал.

function incrementByReference(&$num) {
    $num += 10;
}

$original = 5;
incrementByReference($original);

echo $original; // 15 (изменилась напрямую)

Важные особенности PHP:

  • Объекты передаются по ссылке на объект по умолчанию (начиная с PHP 5). Это означает, что копируется лишь указатель (хэндл) на объект, а не сам объект.
  • Массивы и скалярные типы (int, string, bool и т.д.) передаются по значению.
  • Оптимизация: Передача больших массивов по ссылке может сэкономить память, так как не создается полная копия. Однако с появлением механизма copy-on-write в PHP эта разница стала менее критичной для многих сценариев.

Ответ 18+ 🔞

А, ну это классика, ёпта! Сидишь такой, пишешь код, и тут бац — функция что-то поменяла, а переменная снаружи как была, так и осталась. Или наоборот — поменялась, а ты нихуя не ожидал. Весь сыр-бор из-за того, как данные в функцию попадают.

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

Передача по значению — это когда ты делаешь ксерокс своей бумажки и суёшь копию в функцию. Что она там на этой копии ни рисуй — твой оригинал в кармане останется чистеньким.

function incrementByValue($num) {
    $num += 10;
    return $num;
}

$original = 5;
$result = incrementByValue($original);

echo $original; // 5 (не изменилась, ура!)
echo $result;   // 15 (работали с копией)

Передача по ссылке — это уже по-серьёзному. Ты не копию даёшь, а прямо говоришь: «Вот, держи ссылку на мой кошелёк, работай с ним». И всё, что функция в этом кошельке поменяет — так и останется. Для этого ставишь амперсанд & перед аргументом.

function incrementByReference(&$num) {
    $num += 10;
}

$original = 5;
incrementByReference($original);

echo $original; // 15 (ой, всё! изменили напрямую)

А теперь важные фишки PHP, чтобы не облажаться:

  • Объекты — они особенные, хитрая жопа. Начиная с PHP 5, они по умолчанию передаются как бы «по ссылке на объект». Копируется не сам здоровенный объект, а лишь его «пульт управления». Так что меняешь изнутри — меняется везде. Экономия памяти — овердохуища!
  • Массивы и простые типы (цифры, строки, булевы) — вот они как раз по умолчанию идут по значению. Полная копия, если специально не попросишь ссылку.
  • Про оптимизацию: Раньше, чтобы большой массив не копировать, его специально по ссылке передавали. Сейчас PHP поумнел, появился механизм «копирования при записи» (copy-on-write). То есть пока ты массив только читаешь — копии нет, он один. А как только попытаешься его изменить — вот тогда PHP тихонько сделает его клон и будет мучать уже копию. Так что сейчас не так критично, но знать — полезно, чувак. Вдруг столкнёшься с легаси-кодом, где & на каждом шагу.