Ответ
В PHP механизм передачи аргументов зависит от типа данных.
1. Простые типы (скаляры, массивы) передаются по значению (by value)
Создаётся копия значения переменной. Изменения внутри функции не влияют на оригинальную переменную.
function increment($number) {
$number++; // Работает с копией
echo "Inside function: $numbern"; // Выведет 6
}
$originalNumber = 5;
increment($originalNumber);
echo "Outside function: $originalNumbern"; // Выведет 5 (не изменилась)
2. Передача по ссылке (by reference)
Используя амперсанд (&) в объявлении параметра, функция получает ссылку на оригинальную переменную. Изменения внутри функции влияют на неё.
function incrementByReference(&$number) {
$number++; // Работает с оригинальной переменной
}
$originalNumber = 5;
incrementByReference($originalNumber);
echo $originalNumber; // Выведет 6
3. Объекты передаются по ссылке на объект (object reference)
Начиная с PHP 5, объекты всегда передаются по ссылке на сам объект (формально — передаётся копия хэндла, указывающего на тот же объект).
class User {
public $name = 'Alice';
}
function renameUser($userObject) {
// Изменение свойств объекта видно снаружи
$userObject->name = 'Bob';
}
$user = new User();
echo $user->name; // 'Alice'
renameUser($user); // Объект не клонируется
echo $user->name; // 'Bob' (имя изменилось)
Важное замечание: Если внутри функции переменной с объектом присвоить новый объект, оригинальная переменная снаружи не изменится, так как ссылка перезаписывается только в локальной области видимости.
function replaceUser($userObject) {
$userObject = new User(); // Локальная ссылка теперь на новый объект
$userObject->name = 'Charlie';
}
$user = new User();
$user->name = 'Alice';
replaceUser($user);
echo $user->name; // Останется 'Alice', а не 'Charlie' Ответ 18+ 🔞
А, ну вот, опять про эту передачу аргументов в PHP! Сидишь такой, пишешь код, а потом бац — функция что-то поменяла, а снаружи нихуя не изменилось. Или наоборот, поменяла там что-то, а у тебя всё поехало. Давайте разберёмся, ёпта, без этой ерунды.
1. Простые штуки (числа, строки, массивы) — по значению
Это как взять ксерокопию документа. Меняешь копию — оригинал цел и невредим. Внутри функции ты работаешь с дубликатом.
function increment($number) {
$number++; // Ковыряешь копию
echo "Inside function: $numbern"; // Покажет 6
}
$originalNumber = 5;
increment($originalNumber);
echo "Outside function: $originalNumbern"; // А тут всё ещё 5, оригинал на месте
Вот и вся магия. $originalNumber остался пятеркой, потому что функция терпения ебать ноль имела с ним дело. Ей скормили копию, она её и изменила.
2. А вот если по ссылке — это другое дело
Тут уже ставишь амперсанд (&) перед параметром, и функция получает не копию, а прямую ссылку, как будто дал ей ключи от квартиры. Что внутри поменяешь — то и в оригинале отразится.
function incrementByReference(&$number) {
$number++; // Лепишь прибавку прямо в оригинальную переменную
}
$originalNumber = 5;
incrementByReference($originalNumber);
echo $originalNumber; // Будет 6, ёбана!
Вот это уже серьёзно. Передал по ссылке — будь готов, что твою переменную там впиздюрят как захотят.
3. С объектами — отдельная песня
Начиная с PHP 5, объекты передаются по так называемой «ссылке на объект». Грубо говоря, передаётся не сам ящик с данными, а бумажка с адресом, где этот ящик лежит. Менять содержимое ящика можно, и все это увидят.
class User {
public $name = 'Alice';
}
function renameUser($userObject) {
// Меняешь свойство — меняется у исходного объекта
$userObject->name = 'Bob';
}
$user = new User();
echo $user->name; // 'Alice'
renameUser($user); // Передал "адрес" объекта
echo $user->name; // 'Bob', имя поменялось нахрен!
Но есть нюанс, чувак, хитрая жопа! Если ты внутри функции попытаешься полностью заменить объект на новый (присвоить переменной новый new User()), то оригинальная переменная снаружи этого не почувствует. Потому что ты переписал только локальную «бумажку с адресом», а та, что снаружи, всё ещё указывает на старый ящик.
function replaceUser($userObject) {
$userObject = new User(); // Локальная ссылка теперь на новый объект
$userObject->name = 'Charlie';
}
$user = new User();
$user->name = 'Alice';
replaceUser($user);
echo $user->name; // Останется 'Alice'! Новый 'Charlie' тут никого не ебёт.
Вот так вот, сам от себя охуел, когда впервые с этим столкнулся. Казалось бы, объект, ссылка... ан нет, если переприсваиваешь — накрылся медным тазом твой план. Запомни это, чтобы потом не бздеть по ночам, ища баг.