Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

&$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'];
    }
}
like image 398
zomboble Avatar asked Dec 02 '22 21:12

zomboble


1 Answers

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.

like image 135
3 revs Avatar answered Dec 27 '22 12:12

3 revs