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?

Palec
  • 12,743
  • 8
  • 69
  • 138
yohannan_sobin
  • 907
  • 1
  • 9
  • 17
  • Ref: [Reference - What does this error mean in PHP?](http://stackoverflow.com/q/12769982/367456) – hakre Feb 20 '13 at 10:15
  • Related manual page: [Passing by Reference](http://php.net/manual/en/language.references.pass.php) – Palec Dec 26 '14 at 14:32

2 Answers2

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.

jmc
  • 813
  • 10
  • 18
StasM
  • 10,593
  • 6
  • 56
  • 103
  • 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 :) – Matt Fletcher Sep 11 '13 at 08: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 Sep 11 '13 at 23:57
  • 2
    `First way, you can modify them, other way you can't` the other way around :) – Thierry J. Oct 15 '13 at 04: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
?>
Bailey Parker
  • 15,599
  • 5
  • 53
  • 91
  • 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 Aug 02 '12 at 03: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 Sep 11 '13 at 23:58