Ответ
Нет, по умолчанию аргументы передаются по значению. Это базовое поведение PHP для скалярных типов (int, string, bool, float) и массивов. Функция получает копию значения, и работа ведется с этой копией.
Демонстрация передачи по значению:
function tryToChange($array) {
$array[] = 'new element';
// $array теперь локальная копия, оригинальный массив не изменился
}
$myArray = [1, 2, 3];
tryToChange($myArray);
print_r($myArray); // Выведет Array ( [0] => 1 [1] => 2 [2] => 3 )
Чтобы передать аргумент по ссылке, нужно использовать оператор & в сигнатуре функции:
function actuallyChange(&$array) {
$array[] = 'new element';
}
$myArray = [1, 2, 3];
actuallyChange($myArray);
print_r($myArray); // Выведет Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 'new element' )
Поведение объектов: Объекты передаются по ссылке по умолчанию (начиная с PHP 5). Хотя формально в функцию передается копия дескриптора объекта, эта копия указывает на тот же экземпляр в памяти, поэтому изменения свойств объекта внутри функции сохраняются.
$object = new stdClass();
$object->data = 'original';
function modify($obj) {
$obj->data = 'modified'; // Меняет свойство исходного объекта
}
modify($object);
echo $object->data; // Выведет 'modified' Ответ 18+ 🔞
А, ну это же классика, ёпта! Сидишь такой, пишешь код, думаешь — щас передам массив в функцию, там его поменяю, и всё будет огонь. А потом смотришь — а нихуя не поменялось! Вот тут-то и начинается волнение ебать, и терпения ноль ебать. Так вот, запомни раз и навсегда: по умолчанию всё идёт по значению. То есть функция получает свою собственную, отдельную копию твоего числа, строки или, что чаще всего бесит, массива. Работает с ней, а оригинал лежит себе нетронутый, как святой.
Вот смотри, как это выглядит на практике:
function tryToChange($array) {
$array[] = 'new element';
// $array теперь локальная копия, оригинальный массив не изменился
}
$myArray = [1, 2, 3];
tryToChange($myArray);
print_r($myArray); // Выведет Array ( [0] => 1 [1] => 2 [2] => 3 )
Видишь? Кинул ты массив, думал, что его там дополнят, а он вернулся первозданный. Чистая хитрая жопа, а не поведение. Сам от себя охуеешь, когда впервые с этим столкнёшься.
Но если тебе реально нужно, чтобы функция ковыряла именно твой исходный массив, то надо ей явно сказать. Ставишь перед аргументом в объявлении функции амперсанд & — это как пропуск "бейдж доступа" к оригиналу.
function actuallyChange(&$array) {
$array[] = 'new element';
}
$myArray = [1, 2, 3];
actuallyChange($myArray);
print_r($myArray); // Выведет Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 'new element' )
Вот теперь работает. Функция получила не копию, а ссылку на ту же самую область памяти, где твой массив живёт, и спокойно в него записала.
А теперь про объекты — тут отдельная песня, ебать мои старые костыли. Начиная с пятой пыхи, объекты передаются по так называемой "ссылке на объект". Грубо говоря, ты передаёшь не весь объект (это было бы овердохуища данных), а его "пульт управления". И твоя функция, и ты снаружи — вы дергаете за одни и те же рычаги одного и того же экземпляра.
$object = new stdClass();
$object->data = 'original';
function modify($obj) {
$obj->data = 'modified'; // Меняет свойство исходного объекта
}
modify($object);
echo $object->data; // Выведет 'modified'
Видишь? Без всяких амперсандов объект внутри функции изменился. Это потому что $obj — это не копия всего объекта, а ещё одна переменная, указывающая на того же самого "зверя" в памяти. Так что с объектами доверия ебать ноль — будь осторожен, они меняются везде.