Предупреждение PHP: передача по времени вызова устарела

Я получаю предупреждение: Call-time pass-by-reference has been deprecated для следующих строк кода:

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;
}

Что это вызывает и как это исправить?

2 ответа

Решение

Удалить & от &$this везде это не нужно. На самом деле, я думаю, что вы можете удалить & везде в этом коде - он вообще не нужен.

Длинное объяснение

PHP позволяет передавать переменные двумя способами: "по значению" и "по ссылке". Первый способ ("по значению"), вы не можете изменить их, другой второй способ ("по ссылке"):

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

Обратите внимание & знак. Если я позвоню modified на переменную, она будет изменена, если я позвоню not_modifiedпосле того, как он вернет значение аргумента будет таким же.

Старая версия PHP позволяла имитировать поведение modified с not_modified делая это: not_modified(&$x), Это "время вызова по ссылке". Это устарело и никогда не должно использоваться.

Кроме того, в очень древних версиях PHP (читай: PHP 4 и ранее), если вы изменяете объекты, вы должны передавать их по ссылке, таким образом, используя &$this, Это больше не нужно и не рекомендуется, поскольку объект всегда изменяется при передаче в функцию, т.е. это работает:

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

Это изменило бы $obj->x хотя формально он передается "по значению", но передается дескриптор объекта (как в Java и т. д.), а не копия объекта, как это было в PHP 4.

Это означает, что если вы не делаете что-то странное, вам почти никогда не нужно передавать объект (и, следовательно, $this по ссылке, будь то время звонка или иначе). В частности, ваш код не нуждается в этом.

На случай, если вам интересно, передача по времени вызова по ссылке - устаревшая функция PHP, которая поддерживает свободную типизацию PHP. По сути, он позволяет передавать ссылку (вроде указателя C) на функцию, которая специально не запрашивала ее. Это решение PHP для квадратного колышка в задаче с круглой дырой.
В вашем случае, никогда не ссылаться $this, За пределами класса, ссылка на его $this не позволит вам получить доступ к его закрытым методам и полям.

Пример:

<?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
?>
Другие вопросы по тегам