Если передать объект в функцию, будут ли видны изменения снаружи?

Ответ

Да, изменения свойств переданного объекта внутри функции будут видны снаружи, потому что в PHP объекты передаются по ссылке (точнее, по значению хэндла объекта). Это означает, что функция работает с тем же экземпляром объекта в памяти.

Пример:

class User {
    public $name;
}

function changeName(User $user) {
    $user->name = 'Alice';
}

$user = new User();
$user->name = 'Bob';
changeName($user);
echo $user->name; // Выведет 'Alice'

Важное исключение: Если внутри функции переменной $user присвоить новый объект, это не затронет исходный объект снаружи, так как меняется только локальная ссылка.

function replaceObject(User $user) {
    // Это создаст новый объект, не влияющий на внешнюю переменную
    $user = new User();
    $user->name = 'Eve';
}

Ответ 18+ 🔞

О, ну ты знаешь, тут такая тема интересная, про которую многие ломают голову, а потом охуевают от неожиданных результатов. Речь про то, как объекты в PHP по функциям гуляют.

Смотри, вкратце: если ты передаёшь объект в функцию и внутри этой функции начинаешь его менять — эти изменения останутся и снаружи. Потому что объекты передаются не как примитивы (числа, строки), а по ссылке на тот же самый кусок памяти. Ну, если точнее, по значению хэндла, но это уже детали, суть в том, что ты работаешь с оригиналом, а не с копией.

Вот смотри на пример, тут всё понятно станет:

class User {
    public $name;
}

function changeName(User $user) {
    $user->name = 'Alice';
}

$user = new User();
$user->name = 'Bob';
changeName($user);
echo $user->name; // Выведет 'Alice'

Видишь? Мы внутри функции changeName взяли и переименовали юзера в 'Alice'. И снаружи, после вызова функции, имя тоже поменялось. Потому что это один и тот же объект, ёпта. Не копия, а он самый.

Но! Тут есть один подводный камень, про который многие забывают, а потом волнение ебать какое наступает, когда код ведёт себя не так, как ожидалось. Если ты внутри функции присвоишь переменной $user совершенно новый объект, то внешняя переменная останется нетронутой. Потому что ты меняешь не сам оригинальный объект, а только локальную ссылку на него внутри функции. Она теперь указывает на новый кусок памяти.

function replaceObject(User $user) {
    // Это создаст новый объект, не влияющий на внешнюю переменную
    $user = new User();
    $user->name = 'Eve';
}

Вызови эту функцию, передав туда своего $user — и снаружи он останется прежним. Внутри функции $user стал указывать на нового созданного юзера 'Eve', но как только функция закончилась, эта локальная переменная умерла, а внешняя так и продолжает смотреть на старого юзера.

Так что запомни: менять свойства объекта внутри функции — можно, это отразится везде. А вот пытаться полностью заменить объект на новый, присвоив переменной новый new — бесполезно, это не выйдет за пределы функции. Если тебе нужно именно заменить внешний объект, то придётся либо возвращать новый объект из функции и переприсваивать, либо использовать передачу по ссылке через & (но это уже другая история, и обычно так не делают, потому что мудя это всё).

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