Comments 116
«Кто-либо знает причину этого явления?»
Ну кто-то в интерпретаторе где-то накосячил=)
Ваш К.О.
Ну кто-то в интерпретаторе где-то накосячил=)
Ваш К.О.
+36
Хабрахабр — такой смешной=)
Коммент плюсуют, а карму минисуют=))
Коммент плюсуют, а карму минисуют=))
-27
UFO just landed and posted this here
Неее=) Писал было +10 стало +17=))
Кстати а можно попросить всех заминусовать этот коммент?) (В карму тоже)
Интересно скока получится?)
Я даже могу сказать что PHP это устарелое гамно с дофига фреймворков и библиотек пытающихся это скрыть=))
Кстати а можно попросить всех заминусовать этот коммент?) (В карму тоже)
Интересно скока получится?)
Я даже могу сказать что PHP это устарелое гамно с дофига фреймворков и библиотек пытающихся это скрыть=))
-35
UFO just landed and posted this here
ПХП — не гомно…. Просто руки у некоторых, не там выросли…
+7
Не мотая вниз, прозреваю толпу тупых руби-долбоёбов в комментах, которые там самокомпенсируются.
+2
Если функцию описать заранее, баг не проявляется — смею предположить, это как-то связано с механизмом объявления еще не описанных функий?
0
Это не совсем так.
Пожалуйста смотрите мой коммент ниже: habrahabr.ru/blogs/php/95595/#comment_2919653
Да, в этом случае если функцию описать заранее, баг не проявляется. Но если эту функцию включить в класс, и описать его заранее, то данный баг появится снова во всей своей красе.
Пожалуйста смотрите мой коммент ниже: habrahabr.ru/blogs/php/95595/#comment_2919653
Да, в этом случае если функцию описать заранее, баг не проявляется. Но если эту функцию включить в класс, и описать его заранее, то данный баг появится снова во всей своей красе.
0
Боюсь без исходных кодов тут можно только гадать.
Я бы предположил что там какая-нибудь очередь инициализации переменных сдвигается из-за того что он пытается определить неизвестную переменную, для которой нет значения.
Я бы предположил что там какая-нибудь очередь инициализации переменных сдвигается из-за того что он пытается определить неизвестную переменную, для которой нет значения.
+1
Неприятно… Только вот разве причины бага могут быть интересны? :)
Провел небольшие эксперименты. Судя по всему все объявленные после такого вызова имена становятся ссылками на одну и ту же переменную.
А еще обнаружил, что интерпретатор «чинится», если взять ссылку, типа $z1 = &$z2; (можно абсолютно посторонние переменные).
То есть вот это работает уже корректно:
Провел небольшие эксперименты. Судя по всему все объявленные после такого вызова имена становятся ссылками на одну и ту же переменную.
А еще обнаружил, что интерпретатор «чинится», если взять ссылку, типа $z1 = &$z2; (можно абсолютно посторонние переменные).
То есть вот это работает уже корректно:
<?php f(0, $$var); $zz = &$z; $x = 1; $y = 2; echo $x; function f($a, $b) {}
+5
Лишняя иллюстрация того, что код без предупреждений надёжнее, чем с предупреждениями. ;-)
+2
Либо неописанная фича либо баг, т.к. еще в 5.2 «фича» не работает еще.
+1
Кстати, Автор небось забыл написать, чтобы за баг голосовали :)
0
-доктор, у меня тут болит, когда я делаю так
-не делайте так
этот код логически неверный, он не имеет смысла. просто не делайте так
зы: надеюсь, всем заметно, что в вызове функции используется указание на неопредённую область памяти через неинициализированную переменную
-не делайте так
этот код логически неверный, он не имеет смысла. просто не делайте так
зы: надеюсь, всем заметно, что в вызове функции используется указание на неопредённую область памяти через неинициализированную переменную
+32
Да К.О., но в 5.2 это не проходит :)
0
Это понятно.
Но факт есть факт, что интерпретатор не должен сходить с ума после подобного вызова функции.
В этом случае $$var должен возвращать NULL (что и происходит), и PHP должен кидать нотис «Notice: Undefined variable» (что и делается), но не более того.
Но факт есть факт, что интерпретатор не должен сходить с ума после подобного вызова функции.
В этом случае $$var должен возвращать NULL (что и происходит), и PHP должен кидать нотис «Notice: Undefined variable» (что и делается), но не более того.
+1
я бы даже не notice кидал, а fatal error (лучше даже exception), если пытаются таким образом вызвать фукнцию.
Не должны такие куски кода дальше продолжать работать, т.к. чаще всего они и вызывают недоумение у начинающих, которые просто «забыли» передать какой-либо параметр и получили на выходе совсем не то, что хотели.
Не должны такие куски кода дальше продолжать работать, т.к. чаще всего они и вызывают недоумение у начинающих, которые просто «забыли» передать какой-либо параметр и получили на выходе совсем не то, что хотели.
+2
А мне больше интересно, как вы обнаружили такой баг? )
+17
и долго ли «ржали» и что курили
+2
да-да! +1 реквест фичкейса
+2
Вот тут об том, как это началось: https://www.weblancer.net/forum/themes/17865.html
+2
Так это целый «заповедник» извращенцев :)
+4
UFO just landed and posted this here
Вероятно автор имел ввиду сборщик мусора, который отдельным потоком чистит память.
создание переменных в си и паскале случаются при запуске программы, а уничтожение перед выходом из нее.
А сборщик мусора просто ищет области памяти(переменные), на которую больше нету ссылок и очищает ее. Причем это можно делать сразу после удаления последней ссылки или отдельным потоком. Но в паскале и си, в отличие от Java, такого нету (при работе с памятью), имхо=)
создание переменных в си и паскале случаются при запуске программы, а уничтожение перед выходом из нее.
А сборщик мусора просто ищет области памяти(переменные), на которую больше нету ссылок и очищает ее. Причем это можно делать сразу после удаления последней ссылки или отдельным потоком. Но в паскале и си, в отличие от Java, такого нету (при работе с памятью), имхо=)
+3
Возможно автор этого утверждения просто .NET-разработчик и имел в виду C# и VisualBasic. Впрочем это не меняет фатка, что выражение мутное.
0
На лицо явно новые баги в интерпретатор добавили.
+1
конечно же баг, уже в тот момент, когда разрешили вызывать не декларированые до вызова функции.
Кстати вот такой пример нагляднее:
Кстати вот такой пример нагляднее:
f(0, $$var); function f($a, $b) {} $x = 1; $y = 2; echo $x;
+1
1. PHP допускает вызывать не декларированые до вызова функции, и, хоть это и плохой стиль, но не должно вызывать подобные проблемы интерпретатора.
2. Вот Вам другой пример, где функция заранее задекларирована (как метод класса), но имеем тот же самый дефект, выводится 2, хотя по логике должно было бы быть 1.
<?php
class A {
function f($a, $b) {}
}
$a = new A();
$a->f(0, $$var);
$x = 1;
$y = 2;
echo $x;
?>
2. Вот Вам другой пример, где функция заранее задекларирована (как метод класса), но имеем тот же самый дефект, выводится 2, хотя по логике должно было бы быть 1.
<?php
class A {
function f($a, $b) {}
}
$a = new A();
$a->f(0, $$var);
$x = 1;
$y = 2;
echo $x;
?>
0
Да я и не спорю, что это баг интерпретатора, это я так, немножко поненавидел PHP.
$$var — вот в любом случае странная конструкция, то есть $var то до этого не декларирован — по хорошему надо просто сразу посылать да и всё
$$var — вот в любом случае странная конструкция, то есть $var то до этого не декларирован — по хорошему надо просто сразу посылать да и всё
+2
вот наглядно — если пытаемся передать переменную $ с пустым названием — то получаем баг
<?php
class A {
function f($a, $b) {}
}
$var = '';
$a = new A();
$a->f(0, $$var);
$x = 1;
$y = 2;
$z = 3;
echo $x;
?>
<?php
class A {
function f($a, $b) {}
}
$var = '';
$a = new A();
$a->f(0, $$var);
$x = 1;
$y = 2;
$z = 3;
echo $x;
?>
0
Извините, но чем этот баг «интереснее» тысячи других?
+8
Как по мне, так баги в компиляторах всегда стоит освещать. Потому что это не просто нарушение целостности программы, а очень коварная штука, которая может стоить кому то недели (а то и месяца) головной боли и адского дебага.
+1
Потому что стоило поменять местами аргументы в вызове f() и баг пропадал. Стоило объявить функцию до вызова и баг пропадал. Стоило вместо $x = 1 написать ${x} = 1 и баг пропадал. То есть он был очень нестабильный, и оказался достаточно серьёзным.
+1
UFO just landed and posted this here
переменная переменная.
$b=2;
$a='b';
echo $$a; //2
$b=2;
$a='b';
echo $$a; //2
+15
Спасибо, интересная конструкция, странно что не видел раньше. Наверно считается плохим стилем программирования, отлавливать ошибки с использованием "$$" операция не из легких.
+1
Нет, это не считается плохим стилем программирования. Это просто переменная перменная. Иногда это бывает нужно. А не видели это видимо потому, что вы начинающий программист и просто не было потребности. Но скоро будет.
+3
По-моему абсолютно бесполезная и глупая конструкция. В крайнем случае можно использовать $GLOBALS[$a] вместо $$a, правда опять же, не могу предположить, где это может реально понадобиться так, что без этого или не обойтись, или будет сложный код.
-2
Вы, наверное, и тернарный оператор не используете? ;-)
-2
UFO just landed and posted this here
Я с глобалс привел просто как пример, естественно есть случаи, где его использовать нельзя будет.
Я имел в виду что в общем случае $$var по сути — ассоциативный массив, только без ограничения «области действия». Во всех этих случаях можно воспользоваться обычным ассоциативным массивом.
Я имел в виду что в общем случае $$var по сути — ассоциативный массив, только без ограничения «области действия». Во всех этих случаях можно воспользоваться обычным ассоциативным массивом.
0
Да нет, это плохой стиль, как и много идей заложеных в PHP когда из шаблонизатора решили сделать ООЯП.
В большинстве случаев проще и понятнее $a[$b] или, в крайнем случае, $a->$b.
$b = 'b';
$a = 'b';
$$$a = 'a';
print $$$a; // Happy debugging, bitches :)
В большинстве случаев проще и понятнее $a[$b] или, в крайнем случае, $a->$b.
$b = 'b';
$a = 'b';
$$$a = 'a';
print $$$a; // Happy debugging, bitches :)
+4
" Иногда это бывает нужно."
Ну прям хоть бы вот один примерчик, где это необходимо.
Ну прям хоть бы вот один примерчик, где это необходимо.
+1
Не нашел подсветки html синтаксиса. Ну хорошо. Обьясню на словах.
Есть класс Config. Служебную информацию для классов он берет из файлов, а информацию для более частого изменени из админки. Так надо. У каждого модуля (класса) свои настройки. Дабы не забирать из базы или не создавать один большой файл с настройками мы делим все на подклассы. То есть на модули. Ниже по тексту покажу пример.
Запишу массив пременных из базы в $this->dbConfig, а массив переменных из файлов в $this->fileConfig.
Теперь немного кода.
Можно было бы решить ифом и повторяющимся кодом. Или сделать $array[][][]. Можно найти еще много решений. Но данное самое удобно.
Ну и еще пример — конструктор запросов. $db->$delete->$user->from($array)->where($array). Но такие штуки я не люблю. И не изучал.
Есть класс Config. Служебную информацию для классов он берет из файлов, а информацию для более частого изменени из админки. Так надо. У каждого модуля (класса) свои настройки. Дабы не забирать из базы или не создавать один большой файл с настройками мы делим все на подклассы. То есть на модули. Ниже по тексту покажу пример.
Запишу массив пременных из базы в $this->dbConfig, а массив переменных из файлов в $this->fileConfig.
Теперь немного кода.
public static function get($module, $fromFile = false) {
$ff = $fromFile? 'fileConfigs': 'dbConfigs';
return (isset(self::$$ff[$module][$name]))? self::$$ff[$module][$name]: false;
}
Можно было бы решить ифом и повторяющимся кодом. Или сделать $array[][][]. Можно найти еще много решений. Но данное самое удобно.
Ну и еще пример — конструктор запросов. $db->$delete->$user->from($array)->where($array). Но такие штуки я не люблю. И не изучал.
0
*php ситаксиса
*$this->dbConfigself::dbConfig
*$this->fileConfigself::fileConfig
*Но данное самое удобное. На мой взгляд.
Опечатки. Случайно нажал написать, вместо предпросмотр.
*
*
*Но данное самое удобное. На мой взгляд.
Опечатки. Случайно нажал написать, вместо предпросмотр.
0
Самое удобное? Там где заранее известны возможные значения переменной и их 2 решение очень простое и читается лучше вашего:
$name — вы забыли, кажется.
public static function get($module, $name, $fromFile = false) { $m = $fromFile ? self::fileConfigs[$module] : self::dbConfigs[$module]; return (isset($m[$name])) ? $m[$name] : false; }
$name — вы забыли, кажется.
+1
только self::$fileConfigs (вот за это я тоже не люблю PHP)
0
Да. $name забыл. C браузера плохо писать.
Ваш вариант действительно интересней, читаемей и проще.
Ну рас попросили показать, когда это нужно, то я и показал. Немного не досмотрел. Ну если переменных три или четыре, то использовать ее удобней будет.
Ну и если нужно создать новую переменную, то приходится использовать.
Ваш вариант действительно интересней, читаемей и проще.
Ну рас попросили показать, когда это нужно, то я и показал. Немного не досмотрел. Ну если переменных три или четыре, то использовать ее удобней будет.
Ну и если нужно создать новую переменную, то приходится использовать.
0
UFO just landed and posted this here
Так это целый «заповедник» извращенцев :)
0
На всякий случай… зарепортил его в баг-трекер
Отличная логика. :)
Зарепортили это хорошо, но забыли нажать там ссылку Add a patch и патч, собственно, приложить. :)
-7
причина бага отсутствие строгой типизации и декларации переменных в php и отсутствии культуры программирования у авторов «бага»
-7
> отсутствии культуры программирования у авторов «бага»
А вот такого писать не нужно. Вышеприведенный код не является примером рабочего кода авторов бага, а является специальным демонстрационным примером, предназначенным для выявления проблемы интерпретатора PHP.
Если хотите посмотреть примеры моего кода, могу дать ссылки на какие-либо из моих опенсорсных либ. Ну или погуглите например по слову multicurl. Вот если там найдете ламерство, вот тогда такое про «отсутствии культуры программирования» у автора будете иметь полное право писать. И я буду Вам за это благодарен, так как очень люблю критику в свой адрес.
А вот такого писать не нужно. Вышеприведенный код не является примером рабочего кода авторов бага, а является специальным демонстрационным примером, предназначенным для выявления проблемы интерпретатора PHP.
Если хотите посмотреть примеры моего кода, могу дать ссылки на какие-либо из моих опенсорсных либ. Ну или погуглите например по слову multicurl. Вот если там найдете ламерство, вот тогда такое про «отсутствии культуры программирования» у автора будете иметь полное право писать. И я буду Вам за это благодарен, так как очень люблю критику в свой адрес.
+8
Сам в исходники php не смотрел, но встречал отзывы от одного из лучших специалистов в криптографии (
vitus-wagner, патчи которого есть и в mysql, и в pgsql, и во многих других серьёзных продуктах) — невысокого мнения о php он.
Можно полюбопытствовать, занимательное чтиво.
![](https://habrastorage.org/getpro/habr/post_images/d1b/c9e/d25/d1bc9ed25741859f42b8f4616d5ce567.gif)
Можно полюбопытствовать, занимательное чтиво.
-8
рабинович напел?
0
я совершенно не согласен с этим человеком, будь он хоть господь бог
одна его цитата чего стоит: «Ситуация такова, что разработчик, который понимает что такое БД и зачем она нужна, ни за что не возьмется делать проект на mySQL»
что за бред? тысячи серьезных крупных сайтов с mysql
одна его цитата чего стоит: «Ситуация такова, что разработчик, который понимает что такое БД и зачем она нужна, ни за что не возьмется делать проект на mySQL»
что за бред? тысячи серьезных крупных сайтов с mysql
+4
Вадим очень мощный разработчик
0
Авторы бага — это php team, надо полагать?
0
Авторы «бага» — звучит то как. Можно подумать специально его внесли в код.
+1
UFO just landed and posted this here
Не очень сейчас соображаю, но то, что «var» — зарезервированное слово, не играет роли? Или в этом и суть конструкции?
0
Скорее всего какое-то вмешательство в стековый фрейм (при передачи параметров функции).
0
UFO just landed and posted this here
Не передавайте по ссылке неинициализированные переменные, и всё будет хорошо!
0
Таки да, это не PHP а руки автора.
begemot@ubuntu:/var/www$ php test.php
PHP Notice: Undefined variable: var in /var/www/test.php on line 2
PHP Notice: Undefined variable: in /var/www/test.php on line 2
2
Если у Вас приложения с нотисами, как вы собираетесь баг править?
Странно, а у меня результат, таки 1. Помните про буратино и яблоки?
begemot@ubuntu:/var/www$ php test.php
PHP Notice: Undefined variable: var in /var/www/test.php on line 2
PHP Notice: Undefined variable: in /var/www/test.php on line 2
2
Если у Вас приложения с нотисами, как вы собираетесь баг править?
Странно, а у меня результат, таки 1. Помните про буратино и яблоки?
-1
А оно опять код скушало
$test = 0;
$var = 'test';
f(0, $$var);
$x = 1;
$y = 2;
echo $x;
function f($a, $b) {}
$test = 0;
$var = 'test';
f(0, $$var);
$x = 1;
$y = 2;
echo $x;
function f($a, $b) {}
0
А ещё можно поменять местами аргументы у f и всё будет работать (кстати, проверьте, правда ли это).
Или объявить f до вызова.
Или объявить f до вызова.
0
Да, если объявление функции поместить ранше её вызова, результат 1.
0
А если поменять местами?
Проверить хочу, связано ли это с архитектурой/компилятором.
Проверить хочу, связано ли это с архитектурой/компилятором.
0
Это проблема не PHP а криворукости программиста.
1. использование контрукции $$var
2. не обявление всех переменных
3. вызов функции до её объявления
1. использование контрукции $$var
2. не обявление всех переменных
3. вызов функции до её объявления
-2
Если функцию объявить заранее, то дефект не наблюдается. Но если ее объявить как метод класса (неважно, статический или нет), то дефект все-таки будет.
<?php
class A {
public static function f($a, $b) {}
}
A::f(0, $$wrongvar);
$x = 1;
$y = 2;
echo $x;
?>
Имеем то же дефект.
<?php
class A {
public static function f($a, $b) {}
}
A::f(0, $$wrongvar);
$x = 1;
$y = 2;
echo $x;
?>
Имеем то же дефект.
0
Да, спасибо, я заметил уже это. Очень странное поведение. Я вот только проснулся, сейчас продолжим искать.
0
Это связано с тем, что вызов таких функций (у которых имя не известно до исполнения) происходит динамически, через zend_do_dynamic_function_call.
В этом случае, похоже, часть аргументов каким-то образом передаётся иначе. Самое странное это конечно зависимость от порядка аргументов.
В этом случае, похоже, часть аргументов каким-то образом передаётся иначе. Самое странное это конечно зависимость от порядка аргументов.
0
Это понятно.
Но факт есть факт, что интерпретатор не должен сходить с ума после вызова функции с $$var.
В этом случае $$var должен возвращать NULL (что и происходит), и PHP должен кидать нотис «Notice: Undefined variable» (что и делается), но не более того.
И, надеюсь, под автором Вы имели в виду не меня, а кого-то другого? у меня нет «приложений с нотисами», вышеприведенный пример носит исключительно демонстрационный характер, чтобы показать баг интерпретатора PHP.
Но факт есть факт, что интерпретатор не должен сходить с ума после вызова функции с $$var.
В этом случае $$var должен возвращать NULL (что и происходит), и PHP должен кидать нотис «Notice: Undefined variable» (что и делается), но не более того.
И, надеюсь, под автором Вы имели в виду не меня, а кого-то другого? у меня нет «приложений с нотисами», вышеприведенный пример носит исключительно демонстрационный характер, чтобы показать баг интерпретатора PHP.
0
Вы сказали, что баг проявляется для Win и Linux версий, однако в багрепорте присутствует только Linux: bugs.php.net/bug.php?id=52001
-1
Похоже, что нашёл причину бага: неправильный dereferencing EG(unitialized_zval_ptr).
bugs.php.net/bug.php?id=52001
Будем искать ещё.
bugs.php.net/bug.php?id=52001
Будем искать ещё.
+2
Теперь я могу рассказать, почему это происходило. (Версия PHP 5.3.2)
Во-первых, если вызвать функцию до объявления (или если вызвать её как статическую функцию), будет инициирован вызов по имени (иначе на этапе компиляции по известном имени будет вызвана функция). При вызове по имени аргументы передаются через байткод, помещающий их в стэк аргументов. При вызове по указателю (объявление до вызова) аргументы передаются непосредственно. (Поправьте, если я не прав).
Вызов по имени приводит к тому, что при вызове zend_do_end_variable_parse передаётся arg_offset, нужный для помещения аргументов в стэк (Zend/zend_compile.c стр. 2169). В Zend/zend_compile.c стр. 1066 устанавливалось в этом случае ZEND_FETCH_MAKE_REF, но только если arg_offset был > 0 (для аргументов начиная со второго, что возможно тоже баг).
На этом интересная нам часть компиляции заканчивается.
Теперь, при выполнении, из небытия восстаёт новая переменная: $$var. В этом случае компилятор помещает её в локальный scope EG(active_symbol_table), беря в качестве структуры, хранящей данные, предназначенный для этого &EG(uninitialized_zval). Вернее используется указатель на указатель &EG(uninitialized_zval_ptr).
Далее для получения аргументов функцией вызывается вспомогательная функция zend_fetch_var_address_helper (zend_vm_def.h:4431), которой очень не нравится, что это не reference, и пытается сделать reference «вызовом» SEPARATE_ZVAL_TO_MAKE_IS_REF.
Однако она работает неправильно и перезатирает *variable_ptr_ptr, указывающий на EG(uninitialized_zval). После этого в качестве uninitialized_zval используется уже неправильная структура. У этой структуры refcount=1 (поскольку на неё ссылка лишь одна), в то время как у uninitialized_zval он равен 3.
И теперь фините ля комедия. Из небытия восстают $x, $y, $z, которые так же используют EG(unitialized_zval_ptr), который уже был переписан вызовом SEPARATE_ZVAL_TO_MAKE_IS_REF в другое значение. У этого значения refcount, напомню, равен 1, поэтому оно считается свободным. Из-за этого не создаётся новая структура в Zend/zend_execute.c стр 703 и ниже, а используется существующая все три раза. И последний раз затирает структуру последним значением (стр 708 и ниже в том же файле).
Если написать ${x} = 1, то это вызовет создание переменной не в CV и потому бага не будет.
Во-первых, если вызвать функцию до объявления (или если вызвать её как статическую функцию), будет инициирован вызов по имени (иначе на этапе компиляции по известном имени будет вызвана функция). При вызове по имени аргументы передаются через байткод, помещающий их в стэк аргументов. При вызове по указателю (объявление до вызова) аргументы передаются непосредственно. (Поправьте, если я не прав).
Вызов по имени приводит к тому, что при вызове zend_do_end_variable_parse передаётся arg_offset, нужный для помещения аргументов в стэк (Zend/zend_compile.c стр. 2169). В Zend/zend_compile.c стр. 1066 устанавливалось в этом случае ZEND_FETCH_MAKE_REF, но только если arg_offset был > 0 (для аргументов начиная со второго, что возможно тоже баг).
На этом интересная нам часть компиляции заканчивается.
Теперь, при выполнении, из небытия восстаёт новая переменная: $$var. В этом случае компилятор помещает её в локальный scope EG(active_symbol_table), беря в качестве структуры, хранящей данные, предназначенный для этого &EG(uninitialized_zval). Вернее используется указатель на указатель &EG(uninitialized_zval_ptr).
Далее для получения аргументов функцией вызывается вспомогательная функция zend_fetch_var_address_helper (zend_vm_def.h:4431), которой очень не нравится, что это не reference, и пытается сделать reference «вызовом» SEPARATE_ZVAL_TO_MAKE_IS_REF.
Однако она работает неправильно и перезатирает *variable_ptr_ptr, указывающий на EG(uninitialized_zval). После этого в качестве uninitialized_zval используется уже неправильная структура. У этой структуры refcount=1 (поскольку на неё ссылка лишь одна), в то время как у uninitialized_zval он равен 3.
И теперь фините ля комедия. Из небытия восстают $x, $y, $z, которые так же используют EG(unitialized_zval_ptr), который уже был переписан вызовом SEPARATE_ZVAL_TO_MAKE_IS_REF в другое значение. У этого значения refcount, напомню, равен 1, поэтому оно считается свободным. Из-за этого не создаётся новая структура в Zend/zend_execute.c стр 703 и ниже, а используется существующая все три раза. И последний раз затирает структуру последним значением (стр 708 и ниже в том же файле).
Если написать ${x} = 1, то это вызовет создание переменной не в CV и потому бага не будет.
+13
> При вызове по указателю (объявление до вызова) аргументы передаются непосредственно. (Поправьте, если я не прав).
Вот пример. Функция объявлена до вызова как метод класса, вызывается как не статическая. Но имеем тот же баг.
<?php
class A {
public function f($a, $b) {}
}
$a = new A();
$a->f(0, $$var);
$x = 1;
$y = 2;
echo $x;
?>
В любом случае, спасибо за детальный разбор того, что там происходит внутри. Мы дальше того, чтобы локализовать и зарепортить этот баг, не пошли.
Вот пример. Функция объявлена до вызова как метод класса, вызывается как не статическая. Но имеем тот же баг.
<?php
class A {
public function f($a, $b) {}
}
$a = new A();
$a->f(0, $$var);
$x = 1;
$y = 2;
echo $x;
?>
В любом случае, спасибо за детальный разбор того, что там происходит внутри. Мы дальше того, чтобы локализовать и зарепортить этот баг, не пошли.
0
Не понятно, запатчил ли я его правильно. Это должны узнавать сами разработчики PHP.
В вышеприведённом случае функция так же вызывается динамически. Похоже статически вызываются только функции с явно глобальным пространством времён.
Я сейчас at least напишу хабратопик на тему поиска.
В вышеприведённом случае функция так же вызывается динамически. Похоже статически вызываются только функции с явно глобальным пространством времён.
Я сейчас at least напишу хабратопик на тему поиска.
+2
Кстати:
<?php
$var = 't'; #$t = 10;
f(0, $$var);
$x = 1;
$y = 2;
$z = 3;
echo "$x, $z, $y, $t\n";
function f($a, $b) {}
<?php
$var = 't'; #$t = 10;
f(0, $$var);
$x = 1;
$y = 2;
$z = 3;
echo "$x, $z, $y, $t\n";
function f($a, $b) {}
+1
Sign up to leave a comment.
Интересный баг PHP 5.3