Why should I use a reference operator (&) in a function call?

Customization

I am borrowing a feature from the open source CMS that I often use for a custom project.

The goal does not matter for this question, but if you want to know that it is a simple static cache designed to reduce database queries. I can call getObject 10 times in one page load and not worry about hitting the database 10 times.

the code

A simplified version of the function is as follows:

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 will be called something like this:

 function getObject($object_id) { $object = &staticStorage('object_' . $object_id); if ($object) { return $object; } // This query isn't accurate but that ok it 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 after calling static_storage return value will update the static storage as it changes.

Problem

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

My understanding of pointers is that if I return the pointer, php will automatically add the variable as a pointer $a = &$b will cause $a indicate the value of $b .

Question

Why? If a function returns a link, why should I use a reference operator before calling the function?

+7
pass-by-reference pointers php
source share
2 answers

In 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, this will help the php interpreter. The first use in a function definition is to return a link, and the second is link binding instead of a value to an assignment.

By putting & in the function declaration, the function will return the memory address of the return value. Assignment upon receipt of this memory address interprets the value as int, unless explicitly indicated otherwise, therefore, a second & is required for the assignment operator.

EDIT: As indicated in @ ringΓΈ below, it does not return a memory address, but rather an object that will be processed as a copy (technically copy to write).

+2
source share

The PHP doc explains how to use and why, functions that return links.

In your code, the getObject() function also needs & (and a call), otherwise the link will be lost, and the data, when used, will be based on PHP copy-on-write (the returned data and the original data indicate both the same actual data until there is no change in one of them => two data blocks with a distinct service life)

This will not work (syntax error)

 $a = array(1, 2, 3); return &$a; 

this does not work as intended (the link is not returned)

 $a = array(1, 2, 3); $ref = &$a; return $ref; 

and without adding & to the function call, as you said, the link did not return.

To the question of why ... It seems not a consistent answer.

  • If one of & missing, PHP processes the data as if it was not a reference (e.g. returning an array, for example) without any warnings
  • here's some weirdness with link return functions

PHP has evolved over the years, but still inherits some of the first bad design options. This seems to be one of them (this syntax is error prone, as you can easily skip one & ... and no warning ahead ..., and also why not directly return the link, for example return &$var; ;?) . PHP has made some progress, but still , traces of poor design exist.

You may also be interested in this chapter of the document linked above.

Do not use return-by-reference to improve performance. The engine automatically optimizes this on its own. Return links only when you have the right technical reason.

Finally, it is best not to look too much at the equivalence between pointers to C and PHP references (Perl is closer to PHP in this regard). PHP adds a layer between the actual pointer to the data and the variables, and links point to this layer, not the actual data. But the link is not a pointer. If $a is an array and $b is a reference to $a , using $a or $b to access the array is equivalent. The dereferencing syntax does not exist, and *$b , for example, in C. $b , should be considered an alias of $a . This is also the reason that a function can only return a reference to a variable.

+2
source share

All Articles