Каким образом массив передается в функцию PHP, если внутри функции он не модифицируется?

Ответ

В PHP аргументы, включая массивы, по умолчанию передаются по значению (copy-on-write). Это означает, что при вызове функции создается копия переменной, но физическое копирование данных в памяти происходит только в момент попытки их изменения (write).

Если массив внутри функции только читается, механизм copy-on-write предотвращает лишнее копирование, и передача происходит практически без накладных расходов.

Пример:

function calculateTotal(array $items): float
{
    $total = 0.0;
    // Массив $items только читается
    foreach ($items as $item) {
        $total += $item['price'] * $item['quantity'];
    }
    return $total;
}

$cart = [
    ['name' => 'Book', 'price' => 10, 'quantity' => 2],
    ['name' => 'Pen', 'price' => 1, 'quantity' => 5],
];

$sum = calculateTotal($cart); // Массив передан по значению, но копирования не происходит

Если же нужно явно работать с исходным массивом и изменять его, параметр нужно объявить с передачей по ссылке, используя амперсанд (&).

Ответ 18+ 🔞

Ну слушай, тут такая тема с PHP, что просто ебать мои старые костыли. Все эти разговоры про передачу аргументов — сплошной ёперный театр, пока не разберёшься.

Короче, по умолчанию всё летит в функцию по значению. Это как снять ксерокопию с документа. Но PHP — хитрая жопа, он не копирует всё сразу, а использует хитрый механизм copy-on-write. Представь: ты даёшь другу почитать свою тетрадку с конспектами. Пока он только читает — всё ок, тетрадка одна. Но как только он возьмёт ручку и попытается что-то в ней исправить — тут же выскочит охранник (интерпретатор), хлопнет его по рукам и скажет: «Так, чувак, это чужая тетрадь. Вот тебе чистая, переписывай всё сам и потом уже хуярь что хочешь». Вот это и есть copy-on-write: копирование происходит только при попытке записи. Если внутри функции массив только читают — расходы на копирование, блять, ноль ебать.

Вот смотри, пример:

function calculateTotal(array $items): float
{
    $total = 0.0;
    // Массив $items только читается
    foreach ($items as $item) {
        $total += $item['price'] * $item['quantity'];
    }
    return $total;
}

$cart = [
    ['name' => 'Book', 'price' => 10, 'quantity' => 2],
    ['name' => 'Pen', 'price' => 1, 'quantity' => 5],
];

$sum = calculateTotal($cart); // Массив передан по значению, но копирования не происходит

Видишь? Функция calculateTotal просто бегает по массиву и считает сумму. Она же не меняет сам массив $cart. Поэтому PHP, такой довольный собой, копию даже не создаёт — всё работает быстро, как будто передали по ссылке. Удивление пиздец, да?

Но! Если тебе реально нужно внутри функции покромсать исходный массив — тогда совсем другая история. Тут уже надо явно сказать: «Эй, PHP, дай мне оригинал, а не его фотографию!». Для этого перед параметром в объявлении функции ставишь амперсанд &. Это как дать другу не копию ключей от своей тачки, а оригинал со связки. Теперь он сможет не только покататься, но и вмятину на крыле оставить — будь готов.

function emptyCart(array &$items): void
{
    $items = []; // А вот тут оригинальный массив $cart накрылся медным тазом. Насовсем.
}

Вот и вся магия. Главное — понимать, когда тебе нужна копия, а когда доступ к оригиналу. А то можно так накосячить, что потом полдня искать, куда делись твои данные. Сам от себя охуеешь.