Are arrays in PHP copied as value or as reference to new variables, and when passed to functions?

Solution:1

For the second part of your question, see the array page of the manual, which states (quoting) :

Array assignment always involves value copying. Use the reference operator to copy an array by reference.

And the given example :

<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 is changed,
             // $arr1 is still array(2, 3)

$arr3 = &$arr1;
$arr3[] = 4; // now $arr1 and $arr3 are the same
?>

For the first part, the best way to be sure is to try 😉

Consider this example of code :

function my_func($a) {
    $a[] = 30;
}

$arr = array(10, 20);
my_func($arr);
var_dump($arr);

It’ll give this output :

array
  0 => int 10
  1 => int 20

Which indicates the function has not modified the “outside” array that was passed as a parameter : it’s passed as a copy, and not a reference.

If you want it passed by reference, you’ll have to modify the function, this way :

function my_func(& $a) {
    $a[] = 30;
}

And the output will become :

array
  0 => int 10
  1 => int 20
  2 => int 30

As, this time, the array has been passed “by reference”.

Solution:2

With regards to your first question, the array is passed by reference UNLESS it is modified within the method / function you’re calling. If you attempt to modify the array within the method / function, a copy of it is made first, and then only the copy is modified. This makes it seem as if the array is passed by value when in actual fact it isn’t.

For example, in this first case, even though you aren’t defining your function to accept $my_array by reference (by using the & character in the parameter definition), it still gets passed by reference (ie: you don’t waste memory with an unnecessary copy).

function handle_array($my_array) {  

    // ... read from but do not modify $my_array
    print_r($my_array);

    // ... $my_array effectively passed by reference since no copy is made
}

However if you modify the array, a copy of it is made first (which uses more memory but leaves your original array unaffected).

function handle_array($my_array) {

    // ... modify $my_array
    $my_array[] = "New value";

    // ... $my_array effectively passed by value since requires local copy
}

FYI – this is known as “lazy copy” or “copy-on-write”.