but if it was populating a local array instead of the passed array, wouldn't o --- have totally nothing? but it has crazy,crazy1 etc etc.
It is not so much populating the passed array as causing it to have spurious associative array indices as a side effect.
I suggest that you learn from this example instead:
<?php
function show($words) {
echo implode(' ', $words) . '<br />';
}
function populate(&$words) {
$words = array('Who', 'let', 'the', 'dogs', 'out');
}
function changeWord(&$words) {
$words[3] = 'cats'; // Assume that the element with index 3 exists.
}
$my_words = array();
populate($my_words);
show($my_words);
changeWord($my_words);
show($my_words);
?>
Change changeWord() to use pass by value instead and see what is the effect (or lack thereof). You can also change changeWord() to:
function changeWord(&$words) {
$array[] = &$words[3]; // Assume that the element with index 3 exists.
$array[0] = 'cats';
}
and observe any changes in the output.
For further reading on references, read the PHP manual on references explained.
EDIT:
After the function call, I could actually retrieve $out array with its index name populated.
The crucial difference between that stmt_bind_assoc() function and your testcall() function is that stmt_bind_assoc() goes on to use:
call_user_func_array(mysqli_stmt_bind_result, $fields);
to populate $fields with values, which causes $out to be populated since each element of $fields is an alias for an element of $out. In your example, the first four elements of $fields are aliases of elements of $row, but neither $fields nor $row are actually populated with values, so you have four elements in $row that have indices but are empty.