Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I have to use the reference operator (&) in a function call?

Setup

I am borrowing a function from an open source CMS that I frequently use for a custom project.

It's purpose is not important to this question but if you want to know it's a simple static cache designed to reduce database queries. I can call getObject 10 times in one page load and not have to worry about hitting the database 10 times.

Code

A simplified version of the function looks like this:

function &staticStorage($name, $default_value = NULL)
{
  static $data = array();
  if (isset($data[$name])
  {
    return $data[$name];
  }
  $data[$name] = $default_value;
  return $data[$name];
}

This function would be called in something like this:

function getObject($object_id)
{
  $object = &staticStorage('object_' . $object_id);
  if ($object)
  {
    return $object;
  }

  // This query isn't accurate but that's ok it's not important to the question.
  $object = databaseQuery('SELECT * FROM Objects WHERE id = @object_id', 
                          array('@object_id => $object_id'));
  return $object;
}

The idea is that once I call static_storage the returned value will update the static storage as it is changed.

The problem

My interest is in the line $object = &staticStorage('object_' . $object_id); Notice the & in front of the function. The staticStorage function returns a reference already so I initially did not include the reference operator preceding the function call. However, without the reference preceding the function call it does not work correctly.

My understanding of pointers is if I return a pointer php will automatically cast the variable as a pointer $a = &$b will cause $a to point to the value of $b.

The question

Why? If the function returns a reference why do I have to use the reference operator to precede the function call?

like image 576
danielson317 Avatar asked Jan 21 '16 18:01

danielson317


People also ask

Why do we use reference operator in C++?

The main use of references is acting as function formal parameters to support pass-by-reference. In an reference variable is passed into a function, the function works on the original copy (instead of a clone copy in pass-by-value). Changes inside the function are reflected outside the function.

What is the use of reference operator in C?

Easy To Learn Reference operator (&) In C Language. This referencing operator is also called address operator, which gives the address of a variable, in which location the variable is resided in the memory.

Why do we use reference variable?

A reference variable provides a new name to the existing variable. It is de-referenced implicitly and does not need a de-referencing operator(*) to retrieve the value referenced. Whereas, to retrieve the value pointed to by a pointer we need de-referencing operator(*) which is known as explicit de-referencing.

What is the purpose of reference operator and dereference operator?

I read about * referencing operator and & dereferencing operator; or that referencing means making a pointer point to a variable and dereferencing is accessing the value of the variable that the pointer points to.


1 Answers

From the PHP docs

Note: Unlike parameter passing, here you have to use & in both places - to indicate that you want to return by reference, not a copy, and to indicate that reference binding, rather than usual assignment, should be done for $myValue.

http://php.net/manual/en/language.references.return.php

Basically, its to help the php interpreter. The first use in the function definition is to return the reference, and the second is to bind by reference instead of value to the assignment.

By putting the & in the function declaration, the function will return a memory address of the return value. The assignment, when getting this memory address would interpret the value as an int unless explicitly told otherwise, this is why the second & is needed for the assignment operator.

EDIT: As pointed out by @ringø below, it does not return a memory address, but rather an object that will be treated like a copy (technically copy-on-write).

like image 121
Scott Avatar answered Sep 28 '22 01:09

Scott