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

search for in the

Retourner des références> <Ce que les références ne sont pas
[edit] Last updated: Fri, 25 May 2012

view this page in

Passage par référence

Vous pouvez passer des variables par référence, de manière à ce que la fonction modifie ces variables. La syntaxe est la suivante :

<?php
function foo(&$var) {
  
$var++;
}
$a=5;
foo ($a);
// $a vaut 6 maintenant
?>

Note: Il n'y a pas de signe de référence dans l'appel de la fonction, uniquement sur sa définition. La définition de la fonction est suffisante pour passer correctement des arguments par référence. Dans les versions récentes de PHP, vous devriez recevoir une alerte disant que "Call-time pass-by-reference" est obsolète lorsque vous utilisez un & dans foo(&$a);.

Les objets suivants peuvent être passés par référence :

  • Une variable, i.e. foo($a)
  • Un nouvel objet, i.e. foo(new foobar())
  • Une référence, retournée par une fonction :

    <?php
    function foo(&$var)
    {
        
    $var++;
    }
    function &
    bar()
    {
     
    $a 5;
     return 
    $a;
    }
    foo(bar());
    ?>
    Voir aussi des détails dans retourner des références.

Toutes les autres expressions ne doivent pas être passées par référence, car le résultat sera indéfini. Par exemple, les passages par référence suivants sont invalides :

<?php
function foo(&$var)
{
    
$var++;
}
function 
bar() // Notez l'absence de &
{
   
$a 5;
   return 
$a;
}
foo(bar());    // Produit une erreur fatale depuis PHP 5.0.5

foo($a 5);    // Expression, pas une variable
foo(5);         // Produit une erreur fatale
?>
Ces fonctionnalités sont valables à partir de PHP 4.0.4.



add a note add a note User Contributed Notes Passage par référence
sagiwagi at live dot com 22-May-2012 08:20
It should be noted that documentation above does not fully show
how extract a value from the following code:

<?php
function foo(&$var)
{
   
$var++;
}
function &
bar()
{
   
$a = 5;
    return
$a;
}
foo(bar());
?>

The following will work:

<?php
function foo(&$var)
{
   
$var++;
return
$var;
}
function &
bar()
{
   
$a = 5;
    return
$a;
}
echo
foo(bar());
?>
bkfake-php at yahoo dot com 14-Mar-2012 05:49
It should be noted that
call_user_func_array('function', array(&$a));
is effectively a call-time pass by reference

it should also be noted that it does not throw any error or warning in any version of php.    PHP 5.4 continues to not throw a warning.    Also, as of PHP 5.4, the var will not be passed by reference.
jocelyn dot heuze at gmail dot com 18-Oct-2011 10:12
Please note that you can't pass NULL to a function by reference, unless it's as a default value.

<?php

function foo(&$a = NULL) {
    if (
$a === NULL) {
        echo
"NULL\n";
    } else {
        echo
"$a\n";
    }
}

foo(); // "NULL"
foo(5); // "5"
foo(NULL); // Produces an error

?>
4d88 dot results at gmail dot com 03-May-2011 08:15
This is the way how we use pointer to access variable inside the class.

<?php
class talker{

    private
$data = 'Hi';

    public function &
get(){
        return
$this->data;
    }
   
    public function
out(){
        echo
$this->data;
    }   

}

$aa = new talker();
$d = &$aa->get();

$aa->out();
$d = 'How';
$aa->out();
$d = 'Are';
$aa->out();
$d = 'You';
$aa->out();
?>

the output is "HiHowAreYou"
northhero at gmail dot com 24-Aug-2010 12:25
Someone mentioned that passing reference doesn't work as  expected from within call_user_func(). For example:

<?php
$string
= 'string';
function
change(&$str) {
   
$str = 'str';
}
call_user_func('change', $string);
echo
$string;
?>

output:
string               //not as expected 'str'

Here we could assume call_user_func as below

<?php
function call_user_funct($func, $param) {
   
$func($param);
}
?>

As calling $func() inside call_user_funct, here is change(), the variable $param is copied to a third variable then the temp variable is passed to the $func. So $str only hold the reference of the temp variable inside change().
Of course , if we pass  &$string directly to call_user_func we could always get the result as expected (str).
northhero at gmail dot com 23-Aug-2010 07:02
Passing variable reference to function instead of declaring the function parameter type to reference also could get the result as expected.

<?php
$string
= 'string';
function
change($str) {
   
$str = 'str';
}
change(&$string);
echo
$string;
?>

yeild

str
PhoneixSegovia at GOOGLEMAILSERVER dot com 06-Jul-2010 08:05
If you call it without nothing (no variable, no constant) then a new variable is created with null or the default parameter.
If a null parameter is passed, then this (null) variable is used, even with a default value specified.

A simple example:
<?php

print '<pre>';

function
foo(&$a=5){
   
$a +=2;
    print
"\nIn foo => $a";
}

function
bar(&$a){
   
$a += 2;
    print
"\nIn bar => $a";
}

$a;
$b;
print
"Initial:\n";
var_dump($a, $b);

foo();
bar();

print
"\nAfter void call:\n";
var_dump($a, $b);

foo($a);
bar($b);

print
"\nAfter passed:\n";
var_dump($a, $b);

print
'</pre>';
?>

Output is:
"Initial:
NULL
NULL

In foo => 7
In bar => 2
After void call:
NULL
NULL

In foo => 2
In bar => 2
After passed:
int(2)
int(2)"

Note that null is equal to 0 in a mathematical expresion.
rvw at cosninix dot com 08-Feb-2010 02:13
Watch out that passing an uninitialised variable to a function will create the variable and will NOT give a NOTICE-undefined variable:

<?php
function ifnull(&$v,$default) {
   if (isset(
$v)) return $v;
   return
$default;
}

$p=array();
$p['apple']=3;
echo
ifnull($p['apple'],4);   -> 3
echo ifnull($p['pear'],5);    -> 5  No "undefined index" here.
if (isset(
$p['pear'])) echo "pear is set"; else echo "pear not set"; -> not set
if (array_key_exists('pear',$p)) echo "pear exists"; else echo "pear doesn't exist";  -> pear exists!
?>
Tom 20-Jul-2009 04:54
Still puzzled with references?

See this code:
<?php
function a(&$a, &$b) { $a =& $b; }
$a = 1;
$b = 2;
a($a, $b);
$b = 3;
print
$a;
?>

If you expect the output to be 3, you are wrong. $a remains unchanged and the output is 1. The reference was NOT assigned to $a.

Now let's try this one:
<?php
function a(&$a, &$b) { $a = $b; }
$a = 1;
$b = 2;
a($a, $b);
$b = 3;
print
$a;
?>

If you thought that now the output would be 3, you are wrong again. It's 2.

However this:
<?php
$a
= 1;
$b = 2;
$a =& $b;
$b = 3;
print
$a;
?>
Actually outputs 3.

But how about Objects? Objects, you might think, are always passed by reference. So this should work!

Well, let's check it out:
<?php
function a($a, $b) { $a = $b; }
$a = new StdClass;
$a->i = 1;
$b = new StdClass;
$b->i = 2;
a($a, $b);
$b->i = 3;
print
$a->i;
?>
Outputs 1! So obviously you are wrong again.

What's the reason? Simple! The first (and the last) code example above translates to this fragment:
<?php
$a
= 1;
$b = 2;
$a1 =& $a;
$b1 =& $b;
$a1 =& $b1;
$b = 3;
print
$a;
?>

Now THAT makes it clear, right?

If you are referencing a reference you are NOT making the original pointer change it's destination like in Java or C#, because it is not dereferenced automatically. Instead you are overwriting the local pointer. You will make $a1 point to $b, which has no influence on the original $a.

This is different from all you might expect if you have been programming in other OO-languages before, so you should keep that in mind.
me at khurram dot nl 12-Sep-2008 07:55
in php 5.2.0 for classes

$obj1  =  $obj2;
is equal to
$obj1  =  &$obj2;"

<?php

class z {
    public
$var = '';
    }
 
$a = new z();
$b   =&  $a;
$c  = $a;

$a->var = null;

var_dump($a);
print
'<br>';
var_dump($b);
print
'<br>';
var_dump($c);
print
'<br><br>';

$a->var = 2;

var_dump($a);
print
'<br>';
var_dump($b);
print
'<br>';
var_dump($c);
print
'<br><br>';

?>
mehea 19-May-2008 05:04
New in PHP5:  assign default value to
pass-by-reference paramter.

I didn't believe it even when I read
http://devzone.zend.com/article/1714-Whats-New-in-PHP-5

Then I tried this:

<?php
function my_func(&$arg = 22) {
    if (
$arg == 22) {
        print
'$arg is '. $arg;
    }
}
my_func();
?>

Guess what? It works, even tho' not clear about what $arg is actually referencing!
Chuckie 28-Oct-2007 08:33
If you intend to pass a copy of an object to a function, then you should use 'clone' to create a copy explicity.  In PHP5, objects appear to always be passed by reference (unlike PHP4), but this is not strictly true.

The way I think of it is that if you use '=&' (or you explicitly pass to a function by reference) the variable behaves like a C++ reference, except that you can re-assign the reference to something else (which is not possible in C++).

When you use '=' with an object, it is more like you are dealing with a pointer (if you think in this way, the '->' access element through pointer operator has the same behaviour in C++).

<?php

class z {
    public
$var = '';
    }
  
function
f(&$obj1, $obj2, $obj3, $obj4) {
 
$obj1->var = null;
 
$obj2->var = null;
 
$obj3 = new z();
 
$obj3->var = null;
 
$obj4 = clone $obj4;
 
$obj4->var = null;
  }
$a = new z();
$b = new z();
$c = new z();
$d = new z();
f($a, $b, $c, $d);

var_dump($a); // object(z)#1 (1) { ["var"] => NULL }
var_dump($b); // object(z)#2 (1) { ["var"] => NULL }
var_dump($c); // object(z)#3 (1) { ["var"] => string(0) "" }
var_dump($d); // object(z)#4 (1) { ["var"] => string(0) "" }

?>

Stephen
08-Jul-2007 04:54
jcastromail at yahoo dot es stated:
****
in php 5.2.0 for classes

$obj1  =  $obj2;
is equal to
$obj1  =  &$obj2;"
****

However, that is not completely true. While both = and =& will make a variable refer to the same object as the variable being assigned to it, the explicit reference assignment (=&) will keep the two variables joined to each other, whereas the assignment reference (=) will make the assigned variable an independent pointer to the object. An example should make this clearer:

<?php

class z {
    public
$var = '';
    }
  
$a = new z();
$b   =&  $a;
$c  = $a;

$a->var = null;

var_dump($a);
print
'<br>';
var_dump($b);
print
'<br>';
var_dump($c);
print
'<br><br>';

$a = 2;

var_dump($a);
print
'<br>';
var_dump($b);
print
'<br>';
var_dump($c);
print
'<br><br>';

?>

This outputs:

object(z)#1 (1) { ["var"]=> NULL }
object(z)#1 (1) { ["var"]=> NULL }
object(z)#1 (1) { ["var"]=> NULL }

int(2)
int(2)
object(z)#1 (1) { ["var"]=> NULL }

So although all 3 variables reflect changes in the object, if you reassign one of the variables that were previously joined by reference to a different value, BOTH of those variables will adopt the new value.

Perhaps this is because =& statements join the 2 variable names in the symbol table, whereas = statements applied to objects simply create a new independent entry in the symbol table that simply points to the same location as other entries. I don't know for sure - I don't think this behavior is documented in the PHP manual, so perhaps somebody with more knowledge of PHP's internals can clarify what is going on.
sony-santos at bol dot com dot br 27-Jul-2007 01:06
Just another workaround for default values to parameters by ref in response to mogmios, bobbykjack, andrzej, fdelizy, petruzanautico, Train Boy, and php community.

<?php
# php 4.3.10

# note there's no & in function declaration:
function f($a = array('default value')) {
 
$a[0] .= " processed<br/>";
  echo
$a[0];
}

f(); # default value processed

$b = 'foo';

f(array(&$b)); # foo processed (note the & here)

echo $b; # foo processed
?>
doron 09-Jul-2007 06:06
I found that

f1(&$par=0);

behaves differently in 5.2.4 thatn in 5.0.4
in 5.2.4 the par is assined to zero AFTER function call
and thus, par is allways ZERO !
in 5.0.4 in is INITIALIZED to zero, BEFORE function call!
petruzanautico at yahoo dot com dot ar 25-Sep-2006 01:30
Actually there is a way to give a default value to a reference argument, if you need it badly.
It fires a warning, but you can prefix the function call with an @.
Of course, you cannot pass literals by reference.

<?php
function byref( &$ref )
{
  if( !isset(
$ref ) )
   
$ref = "default value";
  print
$ref; // default or given value? who knows!
}

$hi = "some value ";
byref( $hi ); // works fine
@byref(); // missing argument warning, but works
byref( "hey!" ); // this will raise a fatal error
?>
fdelizy at unfreeze dot net 12-Aug-2006 09:32
Some have noticed that reference parameters can not be assigned a default value. It's actually wrong, they can be assigned a value as the other variables, but can't have a "default reference value", for instance this code won't compile :

<?php
function use_reference( $someParam, &$param =& $POST )
{
 ...
}
?>

But this one will work :

<?php
function use_reference( $someParam, &$param = null )
?>

So here is a workaround to have a default value for reference parameters :

<?php
$array1
= array ( 'test', 'test2' );

function
AddTo( $key, $val, &$array = null)
{
    if (
$array == null )
    {
     
$array =& $_POST;
    }

   
$array[ $key ] = $val ;
}

AddTo( "indirect test", "test", $array1 );
AddTo( "indirect POST test", "test" );

echo
"Array 1 " ;
print_r ( $array1);

echo
"_POST ";
print_r( $_POST );

?>

And this scripts output is :

Array 1 Array
(
    [0] => test
    [1] => test2
    [indirect test] => test
)
_POST Array
(
    [indirect POST test] => test
)

Of course that means you can only assign default reference to globals or super globals variables.

Have fun
rmarscher 15-Sep-2005 03:42
Not sure if this is obvious to everyone, but if you pass an object by reference into a function and then set that variable to the reference of a new object, the initial variable outside the function is still pointing to the original object. 

It became obvious to me why this is the case when I made a little diagram of what's actually happening in the system's memory, but before that when I was just looking at the code, it took me a while of testing before I realized what was going on.

Here's an example (I haven't tried in PHP5, but I would guess it works the same):
<?php
class Foo {}
class
Bar {}

function &
createBar()
{
  return new
Bar;
}

function
setBar(& $obj)
{
  echo
get_class($obj) . "\n";
 
$obj = & createBar();
  echo
get_class($obj) . "\n";
}

$test = new Foo;
setBar($test);
echo
get_class($test);
?>

Outputs:
foo
bar
foo
pillepop2003 at yahoo dot de 13-Feb-2005 08:08
PHP has a strange behavior when passing a part of an array by reference, that does not yet exist.

<?php
   
function func(&$a)
    {
       
// void();
   
}
   
   
$a['one'] =1;
   
func($a['two']);
?>   

var_dump($a) returns

    array(2) {
        ["one"]=>
        int(1)
        ["two"]=>
        NULL
    }

...which seems to be not intentional!
obscvresovl at NOSPAM dot hotmail dot com 25-Dec-2004 10:51
Just a simple note...

<?php

$num
= 1;

function
blah(&$var)
{
   
$var++;
}

blah($num);

echo
$num; #2

?>

<?php

$num
= 1;

function
blah()
{
   
$var =& $GLOBALS["num"];
   
$var++;
}

blah();

echo
$num; #2

?>

Both codes do the same thing! The second code "explains" how passage of parameters by reference works.
jbr at diasparsoftware dot com 28-Sep-2004 09:46
Strangely enough, I had to put "&" on the call site, but not on the function parameter list, in order to get this to work. Here is the code:

<?php
class TestRunner {
    var
$passed;
    var
$failed;
    var
$tests;
   
    function
TestRunner() {
       
$this->passed = 0;
       
$this->failed = 0;
       
$this->tests = array();
    }

    function
addTest($test) {
       
$this->tests[] = $test;
    }

    function
signalFailed() {
       
$this->failed++;
    }
       
    function
runTests() {
        foreach (
$this->tests as $i => $eachName) {
           
call_user_func($eachName, &$this);
        }
    }
       
    function
report() {
       
?>
        <p><?= count($this->tests) ?> run, <?= $this->passed ?> passed, <?= $this->failed ?> failed</p>       
        <?php
   
}
}

function
testNullStringIsEmpty($testRunner) {
   
$testRunner->signalFailed();
}

$testRunner = new TestRunner;
$testRunner->addTest("testNullStringIsEmpty");
$testRunner->runTests();
$testRunner->report();
?>

Notice that testNullStringIsEmpty() does not declare that it wants a reference to a test runner, whereas on the function call site, we pass in &$this. When I run this, I get "1 run, 0 passed, 1 failed"; but when I switch the location of the & to the function parameter list, I get "1 run, 0 passed, 0 failed". This is the exact opposite to what the manual claims. I have no idea why that is.
Sergio Santana: ssantana at tlaloc dot imta dot mx 10-Sep-2004 08:25
Sometimes we need functions for building or modifying arrays whose elements are to be references to other variables (arrays or objects for instance). In this example, I wrote two functions 'tst' and 'tst1' that perform this task. Note how the functions are written, and how they are used.

<?php
function tst(&$arr, $r) {
 
// The argument '$arr' is declared to be passed by reference,
  // but '$r' is not;
  // however, in the function's body, we use a reference to
  // the '$r' argument
 
 
array_push($arr, &$r);
 
// Alternatively, this also could be $arr[] = &$r (in this case)
}
 
$arr0 = array();          // an empty array
$arr1 = array(1,2,3);   // the array to be referenced in $arr0

// Note how we call the function:
tst($arr0, &$arr1); // We are passing a reference to '$arr1' in the call !

print_r($arr0); // Contains just the reference to $arr1

array_push($arr0, 5); // we add another element to $arr0
array_push($arr1, 18); // we add another element to $arr1 as well

print_r($arr1); 
print_r($arr0); // Changes in $arr1 are reflected in $arr0

// -----------------------------------------
// A simpler way to do this:

function tst1(&$arr, &$r) {
 
// Both arguments '$arr' and '$r" are declared to be passed by
  // reference,
  // again, in the function's body, we use a reference to
  // the '$r' argument
 
 
array_push($arr, &$r);
 
// Alternatively, this also could be $arr[] = &$r (in this case)
}

 
$arr0 = array();          // an empty array
$arr1 = array(1,2,3);   // the array to be referenced in $arr0

// Note how we call the function:
tst1($arr0, $arr1); // 'tst1' understands '$r' is a reference to '$arr1'

echo "-------- 2nd. alternative ------------ <br>\n";

print_r($arr0); // Contains just the reference to $arr1

array_push($arr0, 5); // we add another element to $arr0
array_push($arr1, 18);

print_r($arr1); 
print_r($arr0); // Changes in $arr1 are reflected in $arr0

// This outputs:
// X-Powered-By: PHP/4.1.2
// Content-type: text/html
//
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//         )
//
// )
// Array
// (
//     [0] => 1
//     [1] => 2
//     [2] => 3
//     [3] => 18
// )
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//             [3] => 18
//         )
//
//     [1] => 5
// )
// -------- 2nd. alternative ------------
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//         )
//
// )
// Array
// (
//     [0] => 1
//     [1] => 2
//     [2] => 3
//     [3] => 18
// )
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//             [3] => 18
//         )
//
//     [1] => 5
// )
?>

In both cases we get the same result.

I hope this is somehow useful

Sergio.
ben at mekhaye dot net 01-Sep-2004 02:27
Passing arrays by reference doesn't work as I expected from within call_user_func.

I had:

  <?php
  $arr
= Array();
 
call_user_func(Array("ClassName","functionName"), $param1, $param2, $arr);
 
print_r($arr);

  class
ClassName {

     
functionName($param1, $param2, &$arr) {
       
$arr[0] = "apple";
       
$arr[1] = "banana";
       
print_r($arr);
      }
  }
 
?>

I expected the output to be like:

  Array ( [0] => "apple" [1] => "banana" )
  Array ( [0] => "apple" [1] => "banana" )

but instead it was only:

  Array ( [0] => "apple" [1] => "banana" )

However, when I changed the function call to plain old:

  <?php
  $arr
= Array();
 
ClassName::functionName($param1,$param2,$arr);
 
print_r($arr);
 
?>

Output was the expected:

  Array ( [0] => "apple" [1] => "banana" )
  Array ( [0] => "apple" [1] => "banana" )
php at meKILLTHIStatoandthisols dot org 09-Jun-2004 12:33
Ever been in a situation where you have to write:

  <?php
    $t
= 1 ;
   
$x =& $t ;
 
?>

or

  <?php
    $t
= 1 ;
   
f( $t ) ;
 
?>

because you cannot pass constants by value. The function

  <?php
   
function& pclone( $v ) {
      return(
$v ) ;
    }
 
?>

lets you get ridd of the temporary variable. You can write:

  <?php
    $x
=& pclone( 1 ) ;
 
?>

or

  <?php
    f
( pclone( 1 ) ) ;
 
?>

Alternatively you can use the other alternative ;-)
blistwon-php at designfridge dot com 17-Jan-2004 06:33
One thing to note about passing by reference. If you plan on assigning the reference to a new variable in your function, you must use the reference operator in the function declaration as well as in the assignment. (The same holds true for classes.)

<?php
function f1(&$num) {
   
$num++;
}
function
f2(&$num) {
   
$num1 = $num;
   
$num1++;
}
function
f3(&$num) {
   
$num1 = &$num;
   
$num1++;
}

$myNum = 0;
print(
"Declare myNum: " . $myNum . "<br />\n");
f1($myNum);
print(
"Pass myNum as ref 1: " . $myNum . "<br />\n");
f2($myNum);
print(
"Pass myNum as ref 2: " . $myNum . "<br />\n");
f3($myNum);
print(
"Pass myNum as ref 3: " . $myNum . "<br />\n");
?>

-------------------------------------------------------
OUTPUT
-------------------------------------------------------
 Declare myNum: 0
 Pass myNum as ref 1: 1
 Pass myNum as ref 2: 1
 Pass myNum as ref 3: 2
-------------------------------------------------------

Hope this helps people trying to detangle any problems with pass-by-ref.

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