zomboble
zomboble

Reputation: 833

&$variable in PHP

I have been looking through wordpress's core files and stumbled across this piece of code, I noticed it had an ampersand before a variable name and after an =.

I have tried searching this and came across this from the PHP manual and it doesn't explain it well, or I'm looking at the wrong one! I also saw that it is used to modify a variable outside of the method where it is being used, but, thats what a variable is there for, to be modified so if this is correct how would one use it?

function _make_cat_compat( &$category ) {

    if ( is_object( $category ) ) {
        $category->cat_ID = &$category->term_id;
        $category->category_count = &$category->count;
        $category->category_description = &$category->description;
        $category->cat_name = &$category->name;
        $category->category_nicename = &$category->slug;
        $category->category_parent = &$category->parent;
    } elseif ( is_array( $category ) && isset( $category['term_id'] ) ) {
        $category['cat_ID'] = &$category['term_id'];
        $category['category_count'] = &$category['count'];
        $category['category_description'] = &$category['description'];
        $category['cat_name'] = &$category['name'];
        $category['category_nicename'] = &$category['slug'];
        $category['category_parent'] = &$category['parent'];
    }
}

Upvotes: 4

Views: 10340

Answers (5)

ddinchev
ddinchev

Reputation: 34673

This means the function will modify the argument (by reference) instead working on a copy of it. Remove all the ampersands inside the body of the function, only the one in the argument is necessary.

function foo(&$foo) { $foo++; }
function bar($foo) { $foo++; }
$foo = 10;
foo($foo);
foo($foo);

// prints 12, function foo() has incremented var $foo twice
echo "$foo\n";

bar($foo);
// still 12, as bar() is working on a copy of $foo
echo "$foo\n";


// However, since PHP 5.0, all objects are passed by reference [(or to be more specific, by identifier)][1]
class Foo {
    public $bar = 10;
}
$obj = new Foo;
echo "$obj->bar\n"; // 10, as expected

function objectIncrement($obj) { $obj->bar++; }

function objectRefIncrement(&$obj) { $obj->bar++; }

objectIncrement($obj);
echo "$obj->bar\n"; // 11, as expected, since objects are ALWAYS passed by reference (actually by identifier)
objectRefIncrement($obj);
echo "$obj->bar\n"; // 12

It's still a good idea, if you intend to modify the passed argument in a function/method, to explicitly pass it by reference. Aside from other advantages, your code also becomes more explicit and understandable.

BTW, you can do this:

function _make_cat_compat( &$category ) {
    if (is_array( $category)) {
        $category = (object)$category;
    }

    $category->cat_ID = $category->term_id;
    $category->category_count = $category->count;
    $category->category_description = $category->description;
    $category->cat_name = $category->name;
    $category->category_nicename = $category->slug;
    $category->category_parent = $category->parent;
}

Looks cleaner to me, but I don't know your specific case. And I don't know how you would have either array or object - it implies some bad practices used.

Upvotes: 9

nikeee
nikeee

Reputation: 10724

When talking about method parameters, &$variable refers to a call by reference. So any change you make to this variable remains even if the method is done.

function a($arg) // call by value ($arg is a copy of the original)
{
    $arg += 1;
}
function b(&$arg) // call by reference ($arg IS the original)
{
    $arg += 1;
}

$myArg = 1;

a($myArg);
echo $myArg;

echo "\r\n";

b($myArg);
echo $myArg;

// Displays:
// 1
// 2

Here is the section of the PHP manual about references.

The & after the = basically means the same, but they are useless in this context because you already have a call by reference anyway. You can safely remove them.

Upvotes: 7

verenion
verenion

Reputation: 383

It is passing the variable as a reference. Without the ampersand the following code wouldnt work:

$var = "content";

function test(&$v)
{

    $v = "this is new content";

}

test($var);

NOTE: this is untested code, but the theory is close enough. It allows to modify the variable from within a different scope, so rather than passing the value of a variable, in this example - "content", you are passing a reference to the variable itself, so you are directly editing the variable you passed in.

Upvotes: 1

feeela
feeela

Reputation: 29932

Here's the correct PHP manual entry on references: http://php.net/manual/en/language.references.php

In most cases you don't need to pass a reference using the ampersand & as PHP will always pass a reference first and only create a copy of the variable on the first write access.

Upvotes: 1

Alexey Sidorov
Alexey Sidorov

Reputation: 866

Its because this function doesnt return anything, just modify, and all.

Upvotes: 0

Related Questions