User Contributed Notes References Explained |
add a note |
20-Dec-2001 05:46 |
|
Succesive assignement by reference and simple assignement :
$a =
'old';
$b = &$a;
$a = 'new';// now $b's value is new
$c =
$b;// simple copy
$a = 'new new'; // $b is 'new new', $c is still
'new'
And now with arrays :
$a[0] = 'old';
$b =
&$a;
$c = $b;//simple copy
$a[0] = 'new';// $b[0] is new, and
$c[0] is still 'old'
BUT :
$a = 'old';
$b[0] =
&$a;
$c = $b; // simple copy
$a = 'new';//now BOTH $b[0] and
$c[0] are 'new'
A simple copying of an array (or an object) does
NOT
break references for the values (or instance variables).
Use
var_dump() to see which of the values in an array
are
references.
Ivan
|
|
ken at nospam dot notenetwork dot com
11-Jan-2002 02:44 |
|
You may be looking for how to iterate over an array by reference. For
example, you have an array of objects, and you want to call methods that
modify the objects. A normal foreach doesn't work, as the elements of the
array are copied. each() doesn't work either. You have to use a for
loop.
Example of what *COPIES* objects (not what you probably
want):
foreach($object_list as $object) {
$object->method(); }
Example of what does not copy objects
(probably what you want):
for ($c = 0; $c = count($object_list);
$c++) { $object = &$object_list[$c];
$object->method(); }
You get the picture.
|
|
shepnorfleet at comcast dot com
17-Jan-2002 05:55 |
|
Caveat, if your using an associative array with the key pointing to a
reference your going to want to do somehting like
this:
reset($MyArray); while($Key = key($MyArray)) {
$_MyRef = & $MyArray[$Key]; ...Do Smothing...
next($MyArray); }
|
|
cody at iensemble d0t c0m
07-Mar-2002 06:26 |
|
Another way to iterate over an array of references:
foreach
(array_keys($myArray) as $key) {
doSomething($myArray[$key]); }
This works on "normal"
and associative arrays.
|
|
vincent at sunlight dot tmfweb dot NO_SPAM dot nl
27-Mar-2002 11:37 |
|
For the Java programmers among you, there's a big difference between Java
and PHP. In Java, all objects are passed by value (as in PHP). However,
try this in PHP:
class Object { var $value; function
Object() { $this->value = 5; } function getValue()
{ return $this->value; } function setValue($value)
{ $this->value = $value; } }
function
updateObject($object) { $object->setValue($object->getValue() +
5); echo ', ', $object->getValue(); }
$object = new
Object(); echo
$object->getValue(); updateObject($object); echo ', ',
$object->getValue();
It prints: '5, 10, 5'.
If you
implement this same code in Java however, it will print '5, 10,
10'!
Explanation: 'passing by value' in Java means that assigning a
different value to a variable inside a function will not change it outside
a function. (PHP equivalent: '$object = new Object'.) But calling methods
on the variable (when it's an object) can change the object (In PHP:
'$object->setValue(9)'). With PHP the latter isn't true,
unfortunately.
If you use objects in PHP, you have to use
references almost all the time, even if you don't want to assign a new
value to an outside variable, but just want to call methods (that might
update the object).
|
|
henrik dot gebauer at web dot de
02-Apr-2002 08:34 |
|
If you want to check whether there is a reference between two variables you
can use this function.
function check_reference(&$var1,
&$var2) { // Save old values $var1_old = $var1;
$var2_old = $var2; // ($var1 . ".") must not be
$var2 if($var1 . "." == $var2) $var1 .=
".";
// Change $var1 $var1 .=
"."; // Did $var2 also change? if($var2 ==
$var1) $reference = true; else $reference =
false;
// Old values $var1 = $var1_old; $var2 =
$var2_old; return $reference; }
|
|
info at paralight dot ru
08-Apr-2002 10:34 |
|
A have found interesting strange in references to classes.
class
Child{ function Child(&$parent) {
$this->parent=&$parent; $this->parent->var=10; }
function doit() { $this->parent->var=20; } }
class A{ function A() { $this->child=new
Child($this); } function doit() {
$this->child->doit(); echo $this->var; } }
$a = new A; $a->doit();
----------------- In
result we have 10, not 20.
And, if we call $a->doit(); from
constructor �(): function A() { $this->child=new
Child($this); $this->doit(); } we resulting 20.
The
way to takearound this is make empty constructor, move all from it to
function constr(), and run some like:
$a=new A;
$a->me=&$a; $a->constr(); $a->doit();
in
constr() we have $this->child=new Child($this->me); [not
Child($this)].
and, as result we have 20 as would be
expected.
That's this? Am I missunderstand something or it is PHP
bug?
|
|
23-Apr-2002 01:07 |
|
When you do
$a = new A();
PHP creates an object for you,
and returns a COPY of that object So (if I get it right... ) the child
is actually altering the original object and not the copy that you stored
in $a.
However if you do
$a =& new A();
PHP
still creates an object, but returns a REFERENCE to that object. The
child is still altering the original - but you are happy, because you have
got a reference the original!
so if you change the line
$a = new A();
to
$a =& new A();
you'll get
the result you expected.
(BTW wouldn't it be more correct to say
that when you do:
$a = new A()
PHP returns not a copy
but a reference to a copy?)
|
|
vic at NO_SPAM dot altoona dot net
16-Jul-2002 04:20 |
|
Someone compared Java to PHP's pass by value. Java doesn't pass copies of
objects to methods "by value" as PHP does. It passes a copy of
the object's reference by value. It's still the same object. It's
similar to passing a pointer to a structure in C.
|
|
php at fts dot net
16-Jul-2002 05:46 |
|
Note that creating a reference to a non-existing array element causes that
element to be created with a null value. For
example:
var_dump($username); // => NULL var_dump($session);
// => NULL
$username =&
$session['username'];
var_dump($username); // =>
NULL var_dump($session); // => array(1) {
["username"]=> &NULL }
|
|
awriiight at yahoo dot com
01-Oct-2002 07:31 |
|
you can't pass variables by reference when constructing a string:
$a
= "hrack"; $b = "rat" . &$a:
won't work.
|
|
rking at rmode dot com
04-Nov-2002 10:21 |
|
An interesting thing happens when you use a variable that has been set to a
reference as the iterated value in foreach statements. Without unset-ing
the iterated value variable before the foreach, each iteration will change
the content pointed to by the reference.
$field =
&$someVariable; print $someVariable;
// unset($field); //
Without this, the following will probably not work they way you want. It
will set the contents of $someVariable to the current iterated value. It
is left at the end as the last iterated value.
foreach ($fields as
$field) { print $field; }
print $someVariable; // This
won't print out the same as the first one
|
|
marc at schiffbauer dot net
23-Jan-2003 12:13 |
|
If you want to reset a variable which is a reference, you can do that with
the unset() function.
$a = "foo"; $b =
&$a;
$b references to $a now: echo $b // =>
"foo"
$b = NULL; // => now $a is NULL,
too
but:
unset($b); $b = NULL; // => $a is still
"foo" and $b is NULL
|
|
igjav at cesga dot es
05-Mar-2003 11:12 |
|
I've made this testcase to show a case of "self referencing"
applicated to arrays. It seems to point out that must be taken with care,
but only in terms of when is possible to reference.
It's based on
comments over:
Sorry
for the careless sense of key names....
<?
$top =
array ( 'name' => 'top', 'parent' =>
null, 'A' => array ( 'name'
=> 'A', 'element1' => &$top, 'parent'
=> &$top['name'], ), );
$top2 =
array ( 'name' => 'top2', 'parent' =>
null, 'A' => array ( 'name'
=> 'A', 'element1' => &$top, 'parent'
=> &$top['name'], ),
); ?> <pre> <strong><font color=red>
$top = array ( 'name' => 'top', 'parent'
=> null, 'A' => array (
'name' => 'A', 'element1' => &$top,
'parent' => &$top['name'], ), );
$top2
= array ( 'name' => 'top2', 'parent'
=> null, 'A' => array (
'name' => 'A', 'element1' => &$top,
'parent' => &$top['name'], ),
);
</font></strong> top['A']: <? foreach
( $top['A'] as $k => $v ) { printf("$k =>
$v\n"); } // // What happened? //
// Seems
you cannot reference an array element before creating
"completely" the array ?>
This seems to be
"completely" safe:
top2['A']: <? foreach (
$top2['A'] as $k => $v ) { printf("$k =>
$v\n"); } ?>
Then more reference
tests:
<strong><font color=red>
$top['A']['parent'] = $top['name'];
echo($top['A']['parent']); </font></strong>
<?
$top['A']['parent'] = $top['name'];
echo($top['A']['parent']); ?> <strong><font
color=red> $refTop = &$top; $top['A']['parent'] =
$refTop['name'];
echo($top['A']['parent']); </font></strong>
<?
$refTop = &$top; $top['A']['parent'] =
$refTop['name'];
echo($top['A']['parent']); ?> <strong><font
color=red> $top['A']['parent'] = &$top['name'];
echo($top['A']['parent']); </font></strong>
<?
$top['A']['parent'] = &$top['name'];
echo($top['A']['parent']); ?> <strong><font
color=red>
echo($top['A']['element1']['name']); </font></strong>
<?
echo($top['A']['element1']['name']); ?> <strong><font
color=red>
echo($top['A']['element1']['A']['parent']); </font></strong>
<?
echo($top['A']['element1']['A']['parent']); ?> </pre>
|
|
php dot net_usernote at CustomCDROM dot de
26-Mar-2003 02:16 |
|
It should be pointed out that references are UNROLLED if stored in a
session, that is, a copy is made for each reference. If you compare
references to hard links in a Unix file system, as this chapter does,
think of "storing a session" as a "cp -R". That
really bit me when I nearly finished my library and wondered why I could
not use it with PHP's session management. :-/
|
|
thomas at zuschneid dot de
14-Apr-2003 06:27 |
|
I used objects inside objects, like this:
class ItemClass {
function PrintContainerValue() { print
$this->container->value; } }
class ContainerClass
{ var $value=5; function ContainerClass(&$item) {
$item->container = &$this; $this->item = $item;
} }
$aContainer = new ContainerClass(new ItemClass); //
1 $aContainer->value = 10; //
2 $aContainer->item->PrintContainerValue();
It was a long
quest to figure out why this prints 5, not 10. But the solution is
quite simple: The "new" in line 1 creates a ContainerClass
object with value 5 and an item referencing to this instance.
$aContainer gets only a copy whose "value" is changed in
line 2, but item->container still references the first instance with
unchanged "value".
Replacing new with &new solved the
problem.
|
|
chris at chrisderose dot com
24-Apr-2003 11:35 |
|
This caused a good deal of confusion for me today, so I thought I'd share
my findings. Though one might think a variable *should* lose scope at the
end of, say, a for() loop. Its really does not, and any references you set
for that variable will continue to point to the variable in question
during the next iteration. So for example:
$first_var =
NULL;
for ($i=0;$i<5;$i++) { $var = "Hello from
Iteration $i"; if (!$i) $first_var =
&$var; }
echo $first_var;
This code snippet prints
out: "Hello from Iteration 5" and not "Hello from Iteration
0" as one might expect at first glance.
The reason why this
happens is b/c the scope of $var is being retained at the end of the
iteration, and not being unset.
I'm not sure whether this is the
expected behavior or if this is a bug. But to accomplish what we first
intended ( "Hello from Iteration 0" ) We should write the above
code like so:
$first_var = NULL;
for ($i=0;$i<5;$i++)
{ $var = "Hello from Iteration $i"; if (!$i)
$first_var = &$var;
unset($var); // <-- Notice that this
is the only difference }
echo $first_var;
I suspect
there's a number of scope issues that are similar to this and that it
doesn't only affect references. But I don't have the time to find out for
sure. (I'd be very interested to hear from someone who does have the time)
|
|
aflorio at grad dot inf dot puc-rio dot br
06-May-2003 07:32 |
|
The first code snippet above is printing "Hello from Iteration 5"
not only because PHP retains variables after a loop, but because you are
assigning by reference ($first_var = &$var). When you do this,
$first_var becomes an alias of $var. Whatever changes you make in $var
will also change $first_var (they are actually the same). If you
do:
$first_var = NULL; for ($i=0;$i<5;$i++) { $var =
"Hello from Iteration $i"; if (!$i) $first_var =
$var; // Assigning by value } echo $first_var;
Then
you'll get "Hello from Iteration 0". As you can see, it's not
only a matter of variable scoping.
|
|
add a note |