Fatal error: Call-time pass-by-reference has been removed

borodatych

недавненько
Доброго времени суток.
Пока не достиг нужного уровня просветления, поэтому пока задаю глупые вопросы..
Ответ гуглится довольно быстро.
У меня в функции в это месте стояла ссылка:
PHP:
parent::__construct(&$this->arr);
Проект достался в наследство, поэтому не знаю что там задумано + скилов не хватает.
Решил прыгнуть по функции и оказался в:
PHP:
./php/phpstubs/phpruntime/SPL.php
Заглянул, но так и не понял что это.
Ясно одно - это системное и менять тут что то не тру.
Знак ссылки убрал и проект работает локально, в прод такие изменения боюсь вносить.
Вопрос - что хотел сделать прошлый программист?
В этом есть какой то сакральный смысл или он сам не до конца понимал что делал?
Заранее благодарю.
 

Breeze

goshogun
Команда форума
Партнер клуба
наличие ссылки нужно указывать в определении функции
 

Вурдалак

Продвинутый новичок
PHP:
function f($a){
    // ...
}

f(&$a);
=>
PHP:
function f(&$a){
    // ...
}

f($a);
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Вообще, это довольно деструктивное изменение.

Нет, я против просовывания ссылки в нессылочный аргумент, и согласен с тем, что такого быть не должно:

PHP:
function f($x) { ... }
f(&$x)
но не вижу совершенно ничего плохого в такой ситуации:
PHP:
function f(&$x) { ... }
f(&$x)
более того - всегда до 5.4 именно так и писал для ясности и наглядности. Пришлось вычищать.

Я понимаю, что в compile time такой информации нет, но в рантайме же разрулить вполне можно было бы.
 

borodatych

недавненько
Breeze
Ваше:
наличие ссылки нужно указывать в определении функции
Заступорило меня. Я в своем первом посте и написал, что Ответ гуглится довольно быстро.

Мы маленько отклонились от основных вопросов...
 
Последнее редактирование:

WMix

герр M:)ller
Партнер клуба
Вопрос - что хотел сделать прошлый программист?
хотел передать в parent::__construct не копию проперти (значение) $this->arr а саму проперти по адресу.
 
Последнее редактирование:

borodatych

недавненько
Предполагал что этот файл у всех одинаковый и каждый может из своей IDE прыгнуть по функции.
Соль в том что родительская функция выглядит так:
PHP:
public function __construct ($array) {}
И я вообще не вижу смысла в:
PHP:
parent::__construct(&$this->arr);
//Ни в таком варианте
parent::__construct($this->arr);
Даже закомментировать пытался, и сайт вроде как работает, но прод как всегда не стал выпускать, ибо кто его знает что там задумывалось, не весь сайт облазил..
Возможно где то есть переопределение, хотя parent на сколько знаю, должен вызвать функцию из того класса который расширяем и так далее по цепочки наследования.
Но extends ArrayObject уже ни чего не расширяет, а только реализует интерфейсы.
 

Вурдалак

Продвинутый новичок
php/phpstubs/phpruntime/SPL.php — это просто заглушка для IDE, чтобы она знала API тех функций, которые находятся в C-расширениях. Этот код никогда не выполняется. А сам файл с ошибкой в сабже ты нам не показывал.
 

borodatych

недавненько
WMix
Очень благодарен за ответы, но то что передается ссылка на свойство объекта это понятно сразу, и ваш именно такой ответ возможно связан с:
Вурдалак написал(а):
А сам файл с ошибкой в сабже ты нам не показывал.
И в этом моя вина...
Но возможно в заглушках показан не весь механизм, так как в данном коде ни чего не выполняет:
PHP:
//php/phpstubs/phpruntime/SPL.php
public function __construct ($array) {}
И я предположил что это строчка вообще избыточна:
PHP:
parent::__construct(&$this->arr);
Файл Location.php в котором эта строчка, предполагаю целиком можно не подавать?
..если есть смысл, выложу, просто причесывать надо..
А пока, если это прольет свет:
PHP:
class Location extends ArrayObject {
	function __construct() {
		$request = Request::GetInstance();
		$uri = $request->getRequestUri();
		try{ $arr = parse_url($uri); $path = $arr['path']; }
		catch (Exception $e) { $path = $uri; }
		$path = rawurldecode($path);
		$base = $request->getBaseDir();
		$base = str_replace('\\', '/', $base);
		$this->base = $base;
		$this->base .= $base == '/' ? '' : '/';
		if ($path !== $base) $path = substr($path, strlen($base));
		if (substr($path, -1) == '/') $path = substr($path, 0, -1);
		if (substr($path, 0, 1) == '/') $path = substr($path, 1);
		$this->path = $path;
		$this->arr = $path === '' ? array() : explode('/', $path);
		parent::__construct(&$this->arr);
	}
}
С акцентирую...
Зачем в конце вызывать:
PHP:
parent::__construct(&$this->arr);
Если в функции:
PHP:
//php/phpstubs/phpruntime/SPL.php
public function __construct ($array) {}
все равно ни чего не происходит?
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
С акцентирую...
Зачем в конце вызывать:
PHP:
parent::__construct(&$this->arr);
Если в функции:
PHP:
//php/phpstubs/phpruntime/SPL.php
public function __construct ($array) {}
все равно ни чего не происходит?
Отве чаю: тебе уже Вурдалак на пейс ал, что ни чего не про исходит в заглушке, а реальный код надо смотреть в исходниках PHP, на пейс анных на языке Ц. И там переданный в конструктор аргумент таки используется.
 

borodatych

недавненько
WMix, благодарю за ссылку, чего то я совсем расслабился...прошу прощения.
Осмелюсь предположить, до конца не уверен ибо опыта мало, что в самом конце и закралась подсказка:
PHP:
$this->arr = $path === '' ? array() : explode('/', $path);
parent::__construct(&$this->arr);
То есть мы получаем массив, но нам нужно работать как с объектом, поэтому parent от ArrayObject
И даже тут не играет роли, правильно ли я понял или нет.
Допустим, что должна передаться именно ссылка, но в 5.4 так передавать нельзя:
Breeze написал(а):
наличие ссылки нужно указывать в определении функции
Ну не исходники же мне править, но как тогда исправить?
На продакшене php5.3, локально 5.4, ссылка убрана, и каждый раз при коммите я ее возвращаю, что бы не поломать, ибо работает - не трогай.
Тут скорее всего вы мне помочь не сможете, и пока я не изучу код доскональна не понять ответа, может символ ссылки ляпнут туда без осознания надобности, хотя если можно готов выслушать.

Коли заговорили про ссылки, и мысли в теме, то позвольте отвлечься еще на одну ссылку в этом же проекте.
Впервые такое вижу, такое имеет место быть? (даже IDE не ругается):
PHP:
$tree = &$this->make_tree();
И сама функция:
PHP:
function &make_tree() {
  //Code
}
 

AmdY

Пью пиво
Команда форума
PHP:
function foo1($bar){  $bar++; }
function foo2(&$bar){  $bar++; }
$bar = 1;
foo1($bar);
var_dump($bar); // вернёт 1, так как переменню меняли только внутри функции.
foo2($bar); // амперсанд не нужен, он деприкейтид и в пределах php 5+ уж точно можно удалять, в php 4, вроде тоже не нужно было.
var_dump($bar); // вернёт 2, так как в функцию она принялась по ссылке.
второй вариант - присваивает по ссылке.
$a = 1;
$b = &$a;
$a++;
$b // вернёт 2
а вообще почитай книгу, это базовый синтаксис, хотя довольно редко сейчас используемый. в основном популярен был в php 4, когда объекты передавались по значению, а не ссылке. для переменных это довольно геморно, так как php и так использует copy on write.
 

borodatych

недавненько
WMix, благодарю, если честно, то думал что такое выдумка, буду знать.
И мне интересно, как вы нашли?
Скорее всего просто знали, что такая запись - это возвращение по ссылки, чего я не знаю, видимо в силу моего опыта...

AmdY, благодарю за ответ.
С этим знаком, на php.net видел, и есть понимание написанного.
Даже использую ссылки, хотя чаще через свойства объекта стараюсь работать, душе ближе что ли...

..За все ответы спасибо, но.....
Мною-Ранее написал(а):
Ну не исходники же мне править, но как тогда исправить?
На продакшене php5.3, локально 5.4, ссылка убрана, и каждый раз при коммите я ее возвращаю, что бы не поломать, ибо работает - не трогай.
Тут скорее всего вы мне помочь не сможете, и пока я не изучу код доскональна не понять ответа, может символ ссылки ляпнут туда без осознания надобности, хотя если можно готов выслушать.
Вот обновлю я завтра на сервере php до 5.4, и что посоветуете делать?
Могу ли я тупо убрать ссылку? Можно ли сказать, что она там лишняя? Или нужно прочесать каждый символ в проекте и постараться найти тот здравый смысл заложенный в эту ссылку?
 

AmdY

Пью пиво
Команда форума
borodatych
да, конечно, можете смело убирать ссылку parent::__construct(&$this->arr); и оставить parent::__construct($this->arr); это ни на что не повлияет. собственно, ошибка и говорит, что она здесь не нужна.
 

WMix

герр M:)ller
Партнер клуба
И мне интересно, как вы нашли?
если на секунду предположить, что описание всего языка находится на php.net, то можно у гуглов спросить https://www.google.de/search?q=Возвращение+по+ссылке+site:php.net
кстати если нужно просто работать с обьектом как с массивом, можно просто имплементировать ArrayAccess

AmdY
я небыл бы так уверен
PHP:
class A extends ArrayObject {
	public $b = array('c' => "d");

	public function __construct() {
		parent::__construct( $this->b);
	}
}

$a = new A;
print_r( $a );
$a['c'] = "e";
print_r( $a );
Код:
A Object
(
    [b] => Array
        (
            [c] => d
        )

    [storage:ArrayObject:private] => Array
        (
            [c] => d
        )

)
A Object
(
    [b] => Array
        (
            [c] => d
        )

    [storage:ArrayObject:private] => Array
        (
            [c] => e
        )

)
-parent::__construct( $this->b);
+parent::__construct( &$this->b);
Код:
A Object
(
    [b] => Array
        (
            [c] => d
        )

    [storage:ArrayObject:private] => Array
        (
            [c] => d
        )

)
A Object
(
    [b] => Array
        (
            [c] => e
        )

    [storage:ArrayObject:private] => Array
        (
            [c] => e
        )

)
 

borodatych

недавненько
WMix написал(а):
если на секунду предположить, что описание всего языка находится на php.net
))) Я хотел сказать, что я не знал, что это называется именно "Возвращение по ссылки" и гуглил бы что то вроде "php ссылка перед функцией", где получил бы размытые ответы.

И последнее, раз ссылки по стандарту 5.4 в данном месте нельзя, то как обыграть ситуацию?
...доводится только анализ и рефакторинг кода..
 

WMix

герр M:)ller
Партнер клуба
как обыграть ситуацию?
кстати если нужно просто работать с обьектом как с массивом, можно просто имплементировать ArrayAccess
возможно также придется имплементировать Countable, Serializable и тд в зависимости от использования обьекта в программе

))) Я хотел сказать, что я не знал, что это называется именно "Возвращение по ссылки" и гуглил бы что то вроде "php ссылка перед функцией", где получил бы размытые ответы.
https://www.google.ru/search?q=ссылка+site:php.net
ключевое слово site: где искать
 
Последнее редактирование:
Сверху