> В чем разница передачи по значению и по ссылке в PHP (PHP)

Уровень: middle · Роль: backend · Язык: PHP · Категория: Технические вопросы

Компании: vanta

Стек: PHP

> Пример ответа

Короткий ответ

В PHP передача по значению создаёт копию переменной, и изменения внутри функции не влияют на оригинал. Передача по ссылке использует амперсанд & в сигнатуре - функция работает с той же переменной в памяти, и изменения отражаются снаружи. Объекты передаются по идентификатору (handle), что похоже на ссылку, но это не ссылка в строгом смысле. Ссылки в PHP - это alias на переменную, а не указатель.

Подробное объяснение

В PHP по умолчанию все скалярные типы (int, string, float, bool) и массивы передаются по значению. Это означает, что при вызове функции создаётся копия значения, и все операции внутри функции выполняются над этой копией. Оригинальная переменная остаётся неизменной.

Передача по ссылке обозначается символом & перед параметром в объявлении функции. В этом случае параметр становится алиасом (alias) на оригинальную переменную - обе переменные указывают на одно и то же значение в памяти. Любое изменение параметра внутри функции изменяет оригинальную переменную.

Важный нюанс: в PHP ссылки - это не указатели, а именно симлинки на переменные. Когда вы передаёте переменную по ссылке, вы создаёте второе имя для той же ячейки памяти. При этом если внутри функции присвоить параметру новое значение, оригинальная переменная тоже изменится.

Отдельно стоит рассмотреть объекты. В PHP 5+ объекты передаются по идентификатору объекта (object handle). Это не передача по ссылке в классическом смысле, но и не копирование объекта. При передаче объекта в функцию копируется только идентификатор, а сам объект остаётся в памяти один. Поэтому изменения свойств объекта внутри функции видны снаружи, но замена объекта на новый внутри функции не повлияет на оригинальную переменную.

На практике

На практике передача по ссылке используется в нескольких случаях:

  • когда нужно изменить переменную внутри функции и вернуть результат без использования return
  • для экономии памяти при работе с большими массивами (хотя в PHP используется copy-on-write, поэтому реальная копия создаётся только при изменении)
  • в некоторых встроенных функциях, например sort(), preg_match() с третьим параметром

Однако в современном PHP-коде передача по ссылке часто считается плохой практикой, так как она делает код менее предсказуемым. Лучше использовать return-значения или явно возвращать изменённые данные.

Для объектов передача по ссылке обычно не нужна, так как объекты и так мутируются через handle. Но если нужно заменить сам объект на новый внутри функции, тогда ссылка понадобится.

Пример кода

PHP
<?php
// Передача по значению
function addExclamation(string $str): string {
$str .= '!';
return $str;
}
$text = 'hello';
$result = addExclamation($text);
echo $text; // hello - оригинал не изменился
echo $result; // hello!
// Передача по ссылке
function addExclamationByRef(string &$str): void {
$str .= '!';
}
$text = 'hello';
addExclamationByRef($text);
echo $text; // hello! - оригинал изменился
// Объекты - передача по handle
class User {
public string $name = 'John';
}
function renameUser(User $user): void {
$user->name = 'Jane';
}
$user = new User();
renameUser($user);
echo $user->name; // Jane - свойство изменилось
// Но замена объекта внутри функции не сработает без ссылки
function replaceUser(User $user): void {
$user = new User();
$user->name = 'Mike';
}
$user = new User();
replaceUser($user);
echo $user->name; // John - оригинал не заменён
// Чтобы заменить объект, нужна ссылка
function replaceUserByRef(User &$user): void {
$user = new User();
$user->name = 'Mike';
}
$user = new User();
replaceUserByRef($user);
echo $user->name; // Mike

Как отвечать на собеседовании

Начните с базового определения: по значению - копия, по ссылке - alias на переменную. Затем приведите пример с изменением скалярной переменной. Обязательно упомяните объекты и их особенность - передача по handle. Подчеркните разницу между мутацией объекта и заменой объекта. Хорошо добавить, что в PHP используется copy-on-write для массивов, поэтому передача по значению не всегда означает немедленное копирование. Завершите практическим советом: в современном коде предпочтительнее использовать return, а ссылки - только когда это действительно необходимо.

Что проверяет интервьюер

Интервьюер проверяет понимание модели памяти в PHP, отличие ссылок от указателей, знание особенностей работы с объектами. Также важно, что кандидат понимает copy-on-write и умеет объяснить, когда реально происходит копирование. Проверяется способность предсказать поведение кода с ссылками и без них, а также понимание best practices - когда ссылки уместны, а когда лучше избегать.

Типичные ошибки

  • Утверждение, что объекты передаются по ссылке - это неверно, они передаются по handle
  • Путаница между мутацией объекта и заменой объекта
  • Забывают про copy-on-write и думают, что передача массива по значению всегда создаёт полную копию
  • Использование ссылок там, где достаточно return - это усложняет код
  • Непонимание, что ссылка в PHP - это alias, а не указатель, поэтому присваивание нового значения параметру меняет оригинал
  • Ошибка при работе с массивами: передача по ссылке в цикле foreach может привести к неожиданным результатам

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью