4

Codes:

$a = array('email'=>'orange@test','topic'=>'welcome onboard','timestamp'=>'2017-10-6');

$b = array();
foreach($a as $v){
    $b[] = &$v;
}

var_dump($a);
var_dump($b);

Result:

array(3) {
  ["email"]=>
  string(11) "orange@test"
  ["topic"]=>
  string(15) "welcome onboard"
  ["timestamp"]=>
  string(9) "2017-10-6"
}
array(3) {
  [0]=>
  &string(9) "2017-10-6"
  [1]=>
  &string(9) "2017-10-6"
  [2]=>
  &string(9) "2017-10-6"
}

Why the content of $b is not reference of each element of $a? What I expected of $b should be like {&a[0],&a[1],&a[2]} instead of {&a[2],&a[2],&a[2]}

Orange
  • 349
  • 3
  • 13
  • It looks like the root cause is each time $v in foreach is actually same variable space, instead of a whole new variable. For normally 'pass by value situation it works fine, but for 'pass by reference' it results in unexpected situation, unless coder have better understanding about this. – Orange Oct 07 '17 at 03:46

4 Answers4

3

Even i got error when i tried to reference key

$a = array('email'=>'orange@test','topic'=>'welcome onboard','timestamp'=>'2017-10-6');

$b = array();
foreach($a as &$key=>&$v){
    $b[] = &$v;
}

Fatal error: Key element cannot be a reference

Can someone explain to me why you can't pass a key as reference?

Because the language does not support this. You'd be hard-pressed to find this ability in most languages, hence the term key.

So am I stuck with something like this?

Yes. The best way is to create a new array with the appropriate keys.

Any alternatives?

The only way to provide better alternatives is to know your specific situation. If your keys map to table column names, then the best approach is to leave the keys as is and escape them at their time of use in your SQL.

Re: Alternatives to Pass both Key and Value By Reference:

Reference works only for value

<?php

$a = array('email'=>'orange@test','topic'=>'welcome onboard','timestamp'=>'2017-10-6');

$b = array();
foreach($a as $key=>&$v){
    $b[] = &$v;
}
echo "<pre>";
print_r($a);
echo "</pre>";echo "<pre>";
print_r($b);

Output will be

Array
(
    [email] => orange@test
    [topic] => welcome onboard
    [timestamp] => 2017-10-6
)
Array
(
    [0] => orange@test
    [1] => welcome onboard
    [2] => 2017-10-6
)
Vision Coderz
  • 8,257
  • 5
  • 41
  • 57
2

in foreach loop, you set every element of new array $b to reference variable $v. so at the end of foreach loop, they all point to last/current value of $v and that is "2017-10-6".

you can reference elaments of array $a this way:

foreach($a as $k => $var){
    $b[] = &$a[$k];
}
rsm
  • 2,530
  • 4
  • 26
  • 33
0

Reference like this

 foreach($a as &$v){
      $b[] = &$v;
 }

Live demo : https://eval.in/875570

If $a["email"] = "test"; changes it affects to $b automatically

Live demo : https://eval.in/875571

Niklesh Raut
  • 34,013
  • 16
  • 75
  • 109
0

Here is the visa versa referencing. Each element of a reference to each element of b. And reverse referencing is also.

<?php
$a =   
array('email'=>'orange@test','topic'=>'welcome
onboard','timestamp'=>'2017-10-6');
$b = array();
 foreach($a as &$v){
  $b[] = &$v;
 }
  $b[2]='11'; //make changes in any element,  
     //will reflect both array
  var_dump($a);
  var_dump($b);

Here is the working demo: https://ideone.com/icgVJY

Ankur Garg
  • 577
  • 3
  • 9