71

I am getting the warning: Call-time pass-by-reference has been deprecated for the following lines of code:

function XML() {
    $this->parser = &xml_parser_create();
    xml_parser_set_option(&$this->parser, XML_OPTION_CASE_FOLDING, false);
    xml_set_object(&$this->parser, &$this);
    xml_set_element_handler(&$this->parser, 'open','close');
    xml_set_character_data_handler(&$this->parser, 'data');
}
function destruct() {
    xml_parser_free(&$this->parser);
}
function & parse(&$data) {
    $this->document = array();
    $this->stack    = array();
    $this->parent   = &$this->document;
    return xml_parse(&$this->parser, &$data, true) ? $this->document : NULL;
}

What does it cause and how to fix it?

2

2 Answers 2

143

Remove & from &$this everywhere, it is not needed. In fact, I think you can remove & everywhere in this code - it is not needed at all.

Long explanation

PHP allows to pass variables in two ways: "by value" and "by reference". First way ("by value"), you can't modify them, other second way ("by reference") you can:

     function not_modified($x) { $x = $x+1; }
     function modified(&$x) { $x = $x+1; }

Note the & sign. If I call modified on a variable, it will be modified, if I call not_modified, after it returns the value of the argument will be the same.

Older version of PHP allowed to simulate behavior of modified with not_modified by doing this: not_modified(&$x). This is "call-time pass by reference". It is deprecated and should never be used.

Additionally, in very ancient PHP versions (read: PHP 4 and before), if you modify objects, you should pass it by reference, thus the use of &$this. This is neither necessary nor recommended anymore, as object are always modified when passed to function, i.e. this works:

   function obj_modified($obj) { $obj->x = $obj->x+1; }

This would modify $obj->x even though it formally is passed "by value", but what is passed is object handle (like in Java, etc.) and not the copy of the object, as it was in PHP 4.

This means, unless you're doing something weird, you almost never need to pass object (and thus $this by reference, be it call-time or otherwise). In particular, your code doesn't need it.

3
  • May I also point out, the above mentioned error will be shown if you try and call a function using call_user_func('myfunc', &$param) but not if you use call_user_func_array('myfunc', array(&$param)). I don't know why though, if anyone wants to shed any light :) Commented Sep 11, 2013 at 8:21
  • 1
    @MattFletcher Because the former is call-time reference syntax, which has been deprecated for a long time. The latter is just passing arguments to a function (which happens to be call_user_func_array) so there's nothing wrong with it. So yes, you can use this latter syntax to do under-the-radar form of call-time reference, or you can use it for legit purposes - like making wrappers for by-ref variable-args functions (parametrized binds in PDO may be one example). The diff is former is always not legit and not needed, latter may be legit or not legit depending on usage.
    – StasM
    Commented Sep 11, 2013 at 23:57
  • 2
    First way, you can modify them, other way you can't the other way around :)
    – Thierry J
    Commented Oct 15, 2013 at 4:43
20

Just in case you're wondering, a call-time pass by reference is a deprecated PHP feature that promotes PHP loose typing. Basically, it allows you to pass a reference (sort of like a C pointer) to a function that has not specifically asked for one. It's PHP's solution to the square peg in a round hole problem.
In you case, never reference $this. Outside of a class, a reference to its $this will not allow you to access it's private methods and fields.

Example:

<?php
function test1( $test ) {} //This function doesn't want a reference
function test2( &$test ) {} //This function implicitly asks for a reference

$foo = 'bar';
test2( $foo ); //This function is actually given a reference
test1( &$foo ); //But we can't force a reference on test1 anymore, ERROR
?>
2
  • 3
    "Basically, it allows you to pass a reference (sort of like a C pointer) to a function that has not specifically asked for one." <- That's the good stuff. Thanks.
    – RobW
    Commented Aug 2, 2012 at 3:40
  • Just to be clear, PHP references aren't like C pointers at all. They are more like UNIX hardlinks, if you need an analogy.
    – StasM
    Commented Sep 11, 2013 at 23:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.