참조 반환하기

참조에 의한 반환하기는 참조에 연결되어 있는 변수를 찾는 함수를 사용할 때 유용합니다. 참조에 의한 반환을 성능을 증가시키기 위해 사용하지 마십시오. 엔진이 스스로 최적화해 줍니다. 참조를 반환하는건 기술적으로 할 필요가 있을 경우에만 하십시오. 참조를 반환하려면, 다음 문법을 사용합니다:

<?php
class foo {
    public 
$value 42;

    public function &
getValue() {
        
retrun $this->value;
    }
}

$obj = new foo;
$myValue = &$obj->getValue(); // $myValue는 $obj->value의 참조로, 42입니다.
$obj->value 2;
echo 
$myValue;                // $obj->value의 새 값, 즉 2를 출력합니다.
?>
위 예제 코드는 함수 getvalue에 의해 반환하는 객체의 속성을 설정하지만, 참조 문법을 사용하지 않을 때와 같은 복사가 아니다.

Note: 인수 전달과 달리, 여기서는 두 군데에서 &을 사용해야 한다 - 보통의 복사가 아니라, 참조에 의해 반환하는 것을 가리킬 때, 그리고 일반적인 지정이 아닌 참조 연결이라는 것을 가리킬때, $myValue에 대해 사용해야 한다.

Note: 다음 문법으로 함수에서 참조를 반환하려 할 수 있습니다: return ($this->value); 이는 작동하지 않습니다. 변수가 아닌 표현식을 참조로 반환하려고 하는 일이기 때문입니다. 함수에서는 변수만을 참조로 반환할 수 있습니다 - 다른 것은 안됩니다. PHP4의 PHP 4.4.0부터, PHP5의 PHP 5.1.0부터 코드가 동적 표현식이나 new 연산자의 결과를 반환하려 하면, E_NOTICE 오류가 발생합니다.

add a note add a note

User Contributed Notes 19 notes

up
116
Spad-XIII
16 years ago
a little addition to the example of pixel at minikomp dot com here below
<?php

   
function &func(){
        static
$static = 0;
       
$static++;
        return
$static;
    }

   
$var1 =& func();
    echo
"var1:", $var1; // 1
   
func();
   
func();
    echo
"var1:", $var1; // 3
   
$var2 = func(); // assignment without the &
   
echo "var2:", $var2; // 4
   
func();
   
func();
    echo
"var1:", $var1; // 6
   
echo "var2:", $var2; // still 4

?>
up
19
stanlemon at mac dot com
17 years ago
I haven't seen anyone note method chaining in PHP5.  When an object is returned by a method in PHP5 it is returned by default as a reference, and the new Zend Engine 2 allows you to chain method calls from those returned objects.  For example consider this code:

<?php

class Foo {

    protected
$bar;

    public function
__construct() {
       
$this->bar = new Bar();

        print
"Foo\n";
    }   
   
    public function
getBar() {
        return
$this->bar;
    }
}

class
Bar {

    public function
__construct() {
        print
"Bar\n";
    }
   
    public function
helloWorld() {
        print
"Hello World\n";
    }
}

function
test() {
    return new
Foo();
}

test()->getBar()->helloWorld();

?>

Notice how we called test() which was not on an object, but returned an instance of Foo, followed by a method on Foo, getBar() which returned an instance of Bar and finally called one of its methods helloWorld().  Those familiar with other interpretive languages (Java to name one) will recognize this functionality.  For whatever reason this change doesn't seem to be documented very well, so hopefully someone will find this helpful.
up
18
szymoncofalik at gmail dot com
13 years ago
Sometimes, you would like to return NULL with a function returning reference, to indicate the end of chain of elements. However this generates E_NOTICE. Here is little tip, how to prevent that:

<?php
class Foo {
   const
$nullGuard = NULL;
  
// ... some declarations and definitions
  
public function &next() {
     
// ...
     
if (!$end) return $bar;
      else return
$this->nullGuard;
   }
}
?>

by doing this you can do smth like this without notices:

<?php
$f
= new Foo();
// ...
while (($item = $f->next()) != NULL) {
// ...
}
?>

you may also use global variable:
global $nullGuard;
return $nullGuard;
up
12
obscvresovl at NOSPAM dot hotmail dot com
19 years ago
An example of returning references:

<?

$var
= 1;
$num = NULL;

function &
blah()
{
   
$var =& $GLOBALS["var"]; # the same as global $var;
   
$var++;
    return
$var;
}

$num = &blah();

echo
$num; # 2

blah();

echo
$num; # 3

?>

Note: if you take the & off from the function, the second echo will be 2, because without & the var $num contains its returning value and not its returning reference.
up
8
sandaimespaceman at gmail dot com
16 years ago
The &b() function returns a reference of $a in the global scope.

<?php
$a
= 0;
function &
b()
{
    global
$a;
    return
$a;
}
$c = &b();
$c++;
echo
"
\$a:
$a
\$b:
$c
"
?>

It outputs:

$a: 1 $b: 1
up
2
rwruck
18 years ago
The note about using parentheses when returning references is only true if the variable you try to return does not already contain a reference.

<?php
// Will return a reference
function& getref1()
  {
 
$ref =& $GLOBALS['somevar'];
  return (
$ref);
  }

// Will return a value (and emit a notice)
function& getref2()
  {
 
$ref = 42;
  return (
$ref);
  }

// Will return a reference
function& getref3()
  {
  static
$ref = 42;
  return (
$ref);
  }
?>
up
2
civilization28 at gmail dot com
10 years ago
Zayfod's example above is useful, but I feel that it needs more explanation. The point that should be made is that a parameter passed in by reference can be changed to reference something else, resulting in later changes to the local variable not affecting the passed in variable:

<?php

function    & func_b ()
{
   
$some_var = 2;
    return
$some_var;
}

function   
func_a (& $param)
{
   
# $param is 1 here
   
$param = & func_b();    # Here the reference is changed and
                                           # the "&" in "func_a (& $param)"
                                           # is no longer in effect at all.
    # $param is 2 here
   
$param++;    # Has no effect on $var.
}

$var = 1;
func_a($var);
# $var is still 1 here!!!    Because the reference was changed.

?>
up
1
hawcue at yahoo dot com
20 years ago
Be careful when using tinary operation condition?value1:value2

See the following code:

$a=1;
function &foo()
{
  global $a;
  return isset($a)?$a:null;
}
$b=&foo();
echo $b;   // shows 1
$b=2;
echo $a;   // shows 1 (not 2! because $b got a copy of $a)

To let $b be a reference to $a, use "if..then.." in the function.
up
-1
anisgazig at gmail dot com
2 years ago
<?php

$a
= 9;
function &
myF(){
    global
$a;
    return
$a;
}

//before modified the value
$func =& myF();
echo
"$a and $func";
echo
"\n";

//after modified the value
$func++;
echo
"$a and $func";
up
0
fabian dot picone at gmail dot com
6 years ago
This note seems not to apply with PHP 7:

"Note: If you try to return a reference from a function with the syntax: return ($this->value); this will not work as you are attempting to return the result of an expression, and not a variable, by reference. You can only return variables by reference from a function - nothing else. Since PHP 5.1.0, an E_NOTICE error is issued if the code tries to return a dynamic expression or a result of the new operator."

Bug following code works without error output. Same result as i would not have braces around $this-value.

<?php

class foo {
    public
$value = 42;

    public function &
getValue() {
        return (
$this->value);
    }
}

$obj = new foo;
$myValue = &$obj->getValue();
$obj->value = 2;
echo
$myValue;
up
0
benjamin dot delespierre at gmail dot com
13 years ago
Keep in mind that returning by reference doesn't work with __callStatic:

<?php
class Test {
  private static
$_inst;
  public static function &
__callStatic ($name, $args) {
    if (!isset(static::
$_inst)){
      echo
"create";
      static::
$_inst = (object)"test";
   }
   return static::
$_inst;
}

var_dump($a = &Test::abc()); // prints 'create'
$a = null;
var_dump(Test::abc()); // doesn't prints and the instance still exists in Test::$_inst
?>
up
-2
spidgorny at gmail dot com
14 years ago
When returning reference to the object member which is instantiated inside the function, the object is destructed upon returning (which is a problem). It's easier to see the code:

<?php

class MemcacheArray {
    public
$data;

    ...

   
/**
     * Super-clever one line cache reading AND WRITING!
     * Usage $data = &MemcacheArray::getData(__METHOD__);
     * Hopefully PHP will know that $this->data is still used
     * and will call destructor after data changes.
     * Ooops, it's not the case.   
     *
     * @return unknown
     */
   
function &getData($file, $expire = 3600) {
       
$o = new MemcacheArray($file, $expire);
        return
$o->data;
    }
?>

Here, destructor is called upon return() and the reference becomes a normal variable.

My solution is to store objects in a pool until the final exit(), but I don't like it. Any other ideas?

<?php
   
protected static $instances = array();

    function &
getData($file, $expire = 3600) {
       
$o = new MemcacheArray($file, $expire);
       
self::$instances[$file] = $o; // keep object from destructing too early
       
return $o->data;
    }
?>
up
-1
zayfod at yahoo dot com
20 years ago
There is a small exception to the note on this page of the documentation. You do not have to use & to indicate that reference binding should be done when you assign to a value passed by reference the result of a function which returns by reference.

Consider the following two exaples:

<?php

function    & func_b ()
{
   
$some_var = 2;
    return
$some_var;
}

function   
func_a (& $param)
{
   
# $param is 1 here
   
$param = & func_b();
   
# $param is 2 here
}

$var = 1;
func_a($var);
# $var is still 1 here!!!

?>

The second example works as intended:

<?php

function    & func_b ()
{
   
$some_var = 2;
    return
$some_var;
}

function   
func_a (& $param)
{
   
# $param is 1 here
   
$param = func_b();
   
# $param is 2 here
}

$var = 1;
func_a($var);
# $var is 2 here as intended

?>

(Experienced with PHP 4.3.0)
up
-1
php at thunder-2000 dot com
17 years ago
If you want to get a part of an array to manipulate, you can use this function

function &getArrayField(&$array,$path) {
  if (!empty($path)) {
    if (empty($array[$path[0]])) return NULL;
    else return getArrayField($array[$path[0]], array_slice($path, 1));
  } else {
    return $array;
  }
}

Use it like this:

$partArray =& getArrayField($GLOBALS,array("config","modul1"));

You can manipulate $partArray and the changes are also made with $GLOBALS.
up
-2
Anonymous
10 years ago
I learned a painful lesson working with a class method that would pass by reference.  

In short, if you have a method in a class that is initialed with ampersand during declaration, do not use another ampersand when using the method as in &$this->method();

For example
<?php
class A {
    public function &
hello(){
        static
$a='';
        return
$a;
    }
    public function
bello(){
       
$b=&$this->hello();  // incorrect. Do not use ampersand.
       
$b=$this->hello();  // $b is a reference  to the static variable.
}
?>
up
-2
contact at infopol dot fr
20 years ago
A note about returning references embedded in non-reference arrays :

<?
$foo
;

function
bar () {
    global
$foo;
   
$return = array();
   
$return[] =& $foo;
    return
$return;
}

$foo = 1;
$foobar = bar();
$foobar[0] = 2;
echo
$foo;
?>

results in "2" because the reference is copied (pretty neat).
up
-3
willem at designhulp dot nl
19 years ago
There is an important difference between php5 and php4 with references.

Lets say you have a class with a method called 'get_instance' to get a reference to an exsisting class and it's properties.

<?php
class mysql {
    function
get_instance(){
       
// check if object exsists
       
if(empty($_ENV['instances']['mysql'])){
           
// no object yet, create an object
           
$_ENV['instances']['mysql'] = new mysql;
        }
       
// return reference to object
       
$ref = &$_ENV['instances']['mysql'];
        return
$ref;
    }
}
?>

Now to get the exsisting object you can use
mysql::get_instance();

Though this works in php4 and in php5, but in php4 all data will be lost as if it is a new object while in php5 all properties in the object remain.
up
-2
jpenna
4 years ago
You can set the value of the variable returned by reference, be it a `static` function variable or a `private` property of an object (which is quite dangerous o.o).

Static function variable:

<?php
   
function &func(){
        static
$static = 0;
        return
$static;
    }

   
$var1 =& func();
    echo
"var1:", $var1, "\n"; // 0
   
func();
   
   
$var1 = 90;
    echo
"var1:", $var1, "\n"; // 90
   
echo "static:", func(), "\n"; // 90
?>

Private property

<?php
class foo {
    private
$value = 1;

    public function &
getValue() {
        return
$this->value;
    }
   
    public function
setValue($val) {
       
$this->value = $val;
    }
}

$obj = new foo;
$myValue = &$obj->getValue(); // $myValue is a reference to $obj->value, which is 1.
echo $obj->getValue();  // 1
echo $myValue; // 1
$obj->setValue(5);
echo
$obj->getValue();  // 5
echo $myValue; // 5
$myValue = 1000;
echo
$obj->getValue();  // 1000
echo $myValue; // 1000
?>
up
-10
pixel at minikomp dot com
16 years ago
<?php

   
function &func(){
        static
$static = 0;
       
$static++;
        return
$static;
    }

   
$var =& func();
    echo
$var; // 1
   
func();
   
func();
   
func();
   
func();
    echo
$var; // 5

?>
To Top