I don't really understand the part about how array references work (based on the example below).

basically the function testcall will populate a referenced array of $row :

<?php

 $row = array();

 testcall($row);

 function testcall(&$row){
 $fields = array();

$fields[] = &$row["crazy"];
$fields[] = &$row["crazy1"];
$fields[] = &$row["crazy2"];
$fields[] = &$row["crazy3"];
$fields[] = "hahah";

echo "<br>its.. ($fields)";
echo "<br> with size of " . count($fields);

foreach($fields as $key=>$val){
	echo "<br> i --- $key = $val";
}
 }

foreach($row as $key=>$val){
	echo "<br>o --- $key = $val";
}

 echo "<br>statement is now : ($row) with size : " . count($row);
?>

which would output :

its.. (Array)
with size of 5
i --- 0 =
i --- 1 =
i --- 2 =
i --- 3 =
i --- 4 = hahah
o --- crazy =
o --- crazy1 =
o --- crazy2 =
o --- crazy3 =
statement is now : (Array) with size : 4

but i can't understand why both i --- and o --- isn't giving out any values?

    what exactly is this example doing?

    "$fields[] = &$row["crazy"];"

    (assuming first time)

    -$fields[0] = $row["crazy"] = null?
    (since it was never declared that $row["crazy"] had a value.

    and if at o --- why isn't $key = 0 while $val = "crazy" instead?

      The problem is that:

      $fields[] = &$row["crazy"];
      $fields[] = &$row["crazy1"];
      $fields[] = &$row["crazy2"];
      $fields[] = &$row["crazy3"];

      means that you are inserting new elements into $field that are aliases of elements in $row with the associative indices crazy, crazy1, crazy2 and crazy3 respectively... but $row is an empty array, so it has no elements.

      In other words, your testcall() function does not populate the array passed by reference, but populates a local array instead using the array passed. That begs the question of why you are using pass by reference in the first place.

        laserlight wrote:

        In other words, your testcall() function does not populate the array passed by reference, but populates a local array instead using the array passed. That begs the question of why you are using pass by reference in the first place.

        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.

        $fields[] = &$row["crazy"];
        $fields[] = &$row["crazy1"];
        $fields[] = &$row["crazy2"];
        $fields[] = &$row["crazy3"];

        it is as if the above is setting $row[index name] (but itself is empty).

        then it's just weird, if $fields[] was assigned to the reference of $row, shouldn't it show a memory address or a "Array" word when being printed out? that's what's confusing me.

          i was actually trying to understand this code that was written by someone in php.net :

          basically it's a wrapper written for automatically binding results according to statement's field names. After the function call, I could actually retrieve $out array with its index name populated.

          <?php
          function stmt_bind_assoc (&$stmt, &$out) {
              $data = mysqli_stmt_result_metadata($stmt);
              $fields = array();
              $out = array();
          
          $fields[0] = $stmt;
          $count = 1;
          
          while($field = mysqli_fetch_field($data)) {
              $fields[$count] = &$out[$field->name];
              $count++;
          }   
          call_user_func_array(mysqli_stmt_bind_result, $fields);
          }
          

          source : http://www.php.net/manual/en/mysqli-stmt.fetch.php

            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.

              Write a Reply...