PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

Τι δεν είναι οι αναφορές> <Επεξήγηση των αναφορών
Last updated: Sun, 25 Nov 2007

view this page in

Τι κάνουν οι αναφορές

Οι αναφορές στην PHP σας επιτρέπουν να κάνετε δυο μεταβλητές να αναφέρονται στο ίδιο περιεχόμενο. Δηλαδή, όταν γράφετε:

<?php
$a 
=& $b 
?>
σημαίνει ότι η $a και η $b δείχνουν στην ίδια μεταβλητή.

Note: Η $a και η $b είναι τελείως ίσες εδώ, αφού η $a δεν δείχνει στην $b ή αντιστρόφως, αλλά τόσο η $a όσο και η $b δείχνουν στο ίδιο μέρος.

Η ίδια σύνταξη μπορεί να χρησιμοποιηθεί με συναρτήσεις, οι οποίες επιστρέφουν αναφορές, και με τον τελεστή new (στην PHP 4.0.4 και μετά):

<?php
$bar 
=& new fooclass();
$foo =& find_var ($bar);
?>

Note: Η μη χρήση του τελεστή & δημιουργεί ένα αντίγραφο του αντικειμένου που θα γίνει. Αν χρησιμοποιείτε το $this σε μια κλάση, αυτό θα ενεργήσει πάνω στο τρέχον στιγμιότυπο (instance) της κλάσης. Η ανάθεση χωρίς το & θα αντιγράψει το στιγμιότυπο (π.χ. το αντικείμενο) και το $this θα ενεργήσει σ' αυτό το αντίγραφο, το οποίο δεν είναι το επιθυμητό. Συνήθως θέλετε να έχετε ένα μόνο στιγμιότυπο να δουλεύετε, εξαιτίας θεμάτων απόδοσης και κατανάλωσης μνήμης.
Ενώ μπορείτε να χρησιμοποιείτε τον τελεστή @ για να σταματάτε (mute) λάθη στον constructor, όταν το χρησιμοποιείτε ως @new, δε θα δουλέψει όταν κάνετε χρήση και της δήλωσης &new. Αυτό είναι ένας περιορισμός της Zend Engine και συνεπώς θα καταλήξει σε λάθος του μεταγλωττιστή.

Το δεύτερο πράγμα που κάνουν οι αναφορές είναι να περνάνε μεταβλητές με αναφορά (by-reference). Αυτό γίνεται δημιουργώντας μια τοπική μεταβλητή σε μια συνάρτηση και μια μεταβλητή με εμβέλεια τέτοια ώστε να μπορούμε να την καλέσουμε, και η οποία αναφέρεται στο ίδιο περιεχόμενο. Για παράδειγμα:

<?php
function foo (&$var)
{
    
$var++;
}

$a=5;
foo ($a);
?>
Το παραπάνω παράδειγμα θα δώσει στην $a την τιμή 6. Αυτό συμβαίνει γιατί στη συνάρτηση foo η μεταβλητή $var αναφέρεται στο ίδιο περιεχόμενο όπως και η $a. Δείτε πιο λεπτομερή εξήγηση στο πέρασμα με αναφορά (passing by reference).

Το τρίτο πράγμα που κάνουν οι αναφορές είναι η επιστροφή με αναφορά (return by reference).



add a note add a note User Contributed Notes
Τι κάνουν οι αναφορές
dnhuff at acm dot org
09-Jun-2008 11:33
In reply to Drewseph using foo($a = 'set'); where $a is a reference formal parameter.

$a = 'set' is an expression. Expressions cannot be passed by reference, don't you just hate that, I do. If you turn on error reporting for E_NOTICE, you will be told about it.

Resolution: $a = 'set'; foo($a); this does what you want.
Drewseph
29-May-2008 04:15
If you set a variable before passing it to a function that takes a variable as a reference, it is much harder (if not impossible) to edit the variable within the function.

Example:
<?php
function foo(&$bar) {
   
$bar = "hello\n";
}

foo($unset);
echo(
$unset);
foo($set = "set\n");
echo(
$set);

?>

Output:
hello
set

It baffles me, but there you have it.
Amaroq
31-Mar-2008 11:56
The order in which you reference your variables matters.

<?php
$a1
= "One";
$a2 = "Two";
$b1 = "Three";
$b2 = "Four";

$b1 =& $a1;
$a2 =& $b2;

echo
$a1; //Echoes "One"
echo $b1; //Echoes "One"

echo $a2; //Echoes "Four"
echo $b2; //Echoes "Four"
?>
charles at org oo dot com
19-Oct-2007 03:59
points to post below me.
When you're doing the references with loops, you need to unset($var).

for example
<?php
foreach($var as &$value)
{
...
}
unset(
$value);
?>
Hlavac
09-Oct-2007 02:25
Watch out for this:

foreach ($somearray as &$i) {
  // update some $i...
}
...
foreach ($somearray as $i) {
  // last element of $somearray is mysteriously overwritten!
}

Problem is $i contians reference to last element of $somearray after the first foreach, and the second foreach happily assigns to it!
dovbysh at gmail dot com
06-Jul-2007 12:50
Solution to post "php at hood dot id dot au 04-Mar-2007 10:56":

<?php
$a1
= array('a'=>'a');
$a2 = array('a'=>'b');

foreach (
$a1 as $k=>&$v)
$v = 'x';

echo
$a1['a']; // will echo x

unset($GLOBALS['v']);

foreach (
$a2 as $k=>$v)
{}

echo
$a1['a']; // will echo x

?>
amp at gmx dot info
08-Jun-2007 10:59
Something that might not be obvious on the first look:
If you want to cycle through an array with references, you must not use a simple value assigning foreach control structure. You have to use an extended key-value assigning foreach or a for control structure.

A simple value assigning foreach control structure produces a copy of an object or value. The following code

$v1=0;
$arrV=array(&$v1,&$v1);
foreach ($arrV as $v)
{
  $v1++;
  echo $v."\n";
}

yields

0
1

which means $v in foreach is not a reference to $v1 but a copy of the object the actual element in the array was referencing to.

The codes

$v1=0;
$arrV=array(&$v1,&$v1);
foreach ($arrV as $k=>$v)
{
    $v1++;
    echo $arrV[$k]."\n";
}

and

$v1=0;
$arrV=array(&$v1,&$v1);
$c=count($arrV);
for ($i=0; $i<$c;$i++)
{
    $v1++;
    echo $arrV[$i]."\n";
}

both yield

1
2

and therefor cycle through the original objects (both $v1), which is, in terms of our aim, what we have been looking for.

(tested with php 4.1.3)
firespade at gmail dot com
03-Apr-2007 07:11
Here's a good little example of referencing. It was the best way for me to understand, hopefully it can help others.

$b = 2;
$a =& $b;
$c = $a;
echo $c;

// Then... $c = 2
php at hood dot id dot au
04-Mar-2007 10:56
I discovered something today using references in a foreach

<?php
$a1
= array('a'=>'a');
$a2 = array('a'=>'b');

foreach (
$a1 as $k=>&$v)
$v = 'x';

echo
$a1['a']; // will echo x

foreach ($a2 as $k=>$v)
{}

echo
$a1['a']; // will echo b (!)
?>

After reading the manual this looks like it is meant to happen. But it confused me for a few days!

(The solution I used was to turn the second foreach into a reference too)
ladoo at gmx dot at
17-Apr-2005 02:05
I ran into something when using an expanded version of the example of pbaltz at NO_SPAM dot cs dot NO_SPAM dot wisc dot edu below.
This could be somewhat confusing although it is perfectly clear if you have read the manual carfully. It makes the fact that references always point to the content of a variable perfectly clear (at least to me).

<?php
$a
= 1;
$c = 2;
$b =& $a; // $b points to 1
$a =& $c; // $a points now to 2, but $b still to 1;
echo $a, " ", $b;
// Output: 2 1
?>
php.devel at homelinkcs dot com
15-Nov-2004 03:16
In reply to lars at riisgaardribe dot dk,

When a variable is copied, a reference is used internally until the copy is modified.  Therefore you shouldn't use references at all in your situation as it doesn't save any memory usage and increases the chance of logic bugs, as you discoved.
joachim at lous dot org
10-Apr-2003 03:46
So to make a by-reference setter function, you need to specify reference semantics _both_ in the parameter list _and_ the assignment, like this:

class foo{
   var $bar;
   function setBar(&$newBar){
      $this->bar =& newBar;
   }
}

Forget any of the two '&'s, and $foo->bar will end up being a copy after the call to setBar.

 
show source | credits | stats | sitemap | contact | advertising | mirror sites