session.bug_compat_42. ни хрена не понимаю.

Фанат

oncle terrible
Команда форума
session.bug_compat_42. ни хрена не понимаю.

Кто-нибудь разбирается в проблеме настолько, чтобы на пальцах объяснить - какое именно сочетание факторов приводит к появлению этого сообщения?

И как правильно на него реагировать - запретить ли директиву в ини, или менять код? Если менять, то как?
Вот reproduce code
PHP:
session_start();
$_SESSION['login']=$login;
$login=$_GET['login'];
обращение: ttt.php?login=test
при таких вот настройках
Код:
php_flag register_globals 0
php_flag display_errors 1
php_flag session.bug_compat_42 1
комментирование любой строчки в коде приводит к исчезновению ошибки.
убирание переменной login из квери стринг приводит к исчезновению ошибки.
если поменять местами вторую и третью сточку - это приводит к исчезновению ошибки.
смена имени индекса в $_SESSION приводит к исчезновению ошибки
смена имени индекса в $_GET приводит к исчезновению ошибки
присвоение $_SESSION['login'] строкового значения приводит к исчезновению ошибки
присвоение $_SESSION['login'] существующей переменной приводит к исчезновению ошибки
присвоение $_SESSION['login'] несуществующей переменной НЕ приводит к исчезновению ошибки

$subj

-~{}~ 30.12.07 18:20:

Кодблин:
Код:
if (PS(bug_compat) && !PG(register_globals)) {
	HashTable *ht = Z_ARRVAL_P(PS(http_session_vars));
	HashPosition pos;
	zval **val;
	int do_warn = 0;

	zend_hash_internal_pointer_reset_ex(ht, &pos);

	while (zend_hash_get_current_data_ex(ht, (void **) &val, &pos) != FAILURE) {
		if (Z_TYPE_PP(val) == IS_NULL) {
			if (migrate_global(ht, &pos TSRMLS_CC))
				do_warn = 1;
		}
		zend_hash_move_forward_ex(ht, &pos);
	}

	if (do_warn && PS(bug_compat_warn)) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Your script possibly relies on a session side-effect which existed until
 PHP 4.2.3. Please be advised that the session extension does not 
consider global variables as a source of data, unless register_globals is 
enabled. You can disable this functionality and this warning by setting 
session.bug_compat_42 or session.bug_compat_warn to off, 
respectively.");
	}
}
В нём я тоже ничего не понимаю.
 

Андрейка

Senior pomidor developer
какое именно сочетание факторов приводит к появлению этого сообщения расписано ж в мануале - bug_compat_42=1,то сессии будут игнорировать register_globals=0 и создавать свои оч нужные register_global'ные переменные. или вопрос более сложный?
 

Фанат

oncle terrible
Команда форума
Более.
Как мне кажется.

Как минимум, одной из причин является наличие в одном из суперглобалов элемента с именем, совпадающим ключом в _SESSION (рекурсия, блин!!!), и отсутствие присвоения элементу _SESSION знаения...

постой. "создавать register_globaные переменные" - ты имеешь в виду пихать в глобальную область видимости переменную с таким именем? Щас попробую...

-~{}~ 30.12.07 18:36:

нет, вроде...
код
PHP:
session_start();
$_SESSION['login']=$login;
var_dump($login);
$login=$_GET['login'];
выдаёт Ошибку и NULL

-~{}~ 30.12.07 18:44:

Хотя код
PHP:
session_start();
session_register("test");
var_dump($_SESSION["test"]);
$test = 1;
выводит NULL и Ошибку при ПУСТОЙ(!) адресной строке!
Т.е. при отсуствии элемента test во всех суперглобалах.
причем только в первый проход. при обновлении старницы ошибка пропадает.

Я или чего-то не понимаю или жестоко туплю...
 

FractalizeR

Новичок
Проблема (т.е. баг PHP) похоже, состоял в том, что в SESSION записывается содержимое "супер-глобальной" (supoerglobal) переменной (элемента массивов $_SERVER, $_POST и т.д.), либо переменной со значением null (значение не определено):
http://qaix.com/php-web-programming/152-404-sessions-and-global-register-read.shtml
http://bugs.php.net/bug.php?id=21312

Если сначала передать значение из глобального массива в локальную для скрипта переменную (что вы и делаете меняя вторую и третью строки местами), проблема исчезает.
 

Фанат

oncle terrible
Команда форума
Что-то мне это сомнительно. Мне кажется, что в сессию записывается значение не суперглобальной, а просто глобальной переменной. Даже при регистер жлобалс-офф. Собственно, регистер глобалс и имеет отношение только к глобальным переменным, а не к элементам суперглобальных массивов.

Но да, заявление Endeveit меня тоже сбивает с толку.
Мне кажется, что код
$_SESSION['var'] = $_REQUEST['var'];
не может вызывать эту ошибку.

-~{}~ 30.12.07 19:24:

Вообще, меня в вопросе интересует не столько исправление ошибки, сколько её ПОЯВЛЕНИЕ.
 

FractalizeR

Новичок
Так вот я и говорю, что ошибка, видимо, появляется тогда, когда элементу $_SESSION присваивается значение элемента superglobal массива или значение null.
 

Фанат

oncle terrible
Команда форума
это не единственное условие.
если просто присваивать, то ни хрена не будет

слушай, да вай ты будешь проверять свои слова перед тем, как писать, как я это делаю, а?
чтобы меньше было воды в топике.

-~{}~ 30.12.07 20:59:

если так.
есть сессионная переменная без значения
а ниже в скрипте присваивается значение одноименнаой глобальной переменной.
а?
оба имеющихся примера - с решн_регистер и с массивом в этом случае предстают практически одинаковыми (чего я очень хотел добиться)

а суперглобалы тут вообще, похоже, не при чём.

Блин неужели никому, кроме меня, не интересно?

-~{}~ 30.12.07 21:41:

Если я прав, то Ошибке всегда должен сопутствовать нотис о несуществующей переменной.
Это если я прав...
 

DYPA

Настоящая dypa (c)
PHP versions 4.2.3 and lower have an undocumented feature/bug that allows you to initialize a session variable in the global scope, albeit register_globals is disabled. PHP 4.3.0 and later will warn you, if this feature is used, and if session.bug_compat_warn is also enabled. This feature/bug can be disabled by disabling this directive.
думаю так будет понятно что происходит:
test.php?login=string
Код:
<?php
session_start();

var_dump($_SESSION['var']); //string после рефреша
$_SESSION['var'] = $x;
var_dump($_SESSION['var']); //null
$var = $_GET['login'];
var_dump($_SESSION['var']); //null

//session.bug_compat_42 = 0 ; выключает это фичу
//null
//null
//null
 

Фанат

oncle terrible
Команда форума
Нет, непонятно.
Ты можешь написать словами?

-~{}~ 31.12.07 13:14:

если так.
есть сессионная переменная без значения
а ниже в скрипте присваивается значение одноименной глобальной переменной.
нифига. первый пример блин нафиг всё опровергает, абанамат.

если к первому скрипту обратиться с логином в кверистринге, то ошибка вылазит. если без - не вылазит.

если поменять последнюю строчку на $login=""; то вылазит в любом случае.
 

DYPA

Настоящая dypa (c)
PHP < 4.2.4 имеют недокументированный баг (фичу), который позволяет инициализировать переменную в сессии через глобальную, даже когда register_globals = off. Начиная с PHP 4.3.0 мы предупреждаем вас что используется такая фича.
http://lingvo.yandex.ru/
если по русски то $_SESSION['var'] берется из переменной $var, как будто register_globals = on
 

Фанат

oncle terrible
Команда форума
Мда. Это теория. Это хорошо.
Но если бы всё было так просто, то код
session_start();
$_SESSION['login']=$login;
$login=$_GET['login'];

всегда приводил бы к появлению ошибки. а он приводит не всегда.
но кажется, я начинаю понимать - кода...

-~{}~ 31.12.07 14:50:

Да, кажется, разобрался. Противоречий, вроде, нет...

-~{}~ 31.12.07 14:58:

DYPA
Ты просто пересказываешь документацию.
А меня интересовала консультация человека, который понял, почему так происходит.

Под твоё объяснение попадает простой скрипт

$_SESSION['login']="";
$login="user";

а он ошибку не вызывает. хотя казалось бы

-~{}~ 31.12.07 15:10:

В принципе, я сам виноват. В том, что нечетко сформулировал вопрос.
Меня интересовал принцип, на основании которого пых выкидывает ошибку. Чтобы я могу посмотреть на код и сказать - "он выдаст ошибку". Или не выдаст.
Как я могу это сказать для регистер глобалс, например.

Вообще, насколько я понимаю, это совершенно лишний варнинг, вместо которого достаточно было примечания к доке.

-~{}~ 31.12.07 15:14:

После того, как разгобрался эмпирическим путём, сразу стал лучше понимать сишный исходник =)
 

DYPA

Настоящая dypa (c)
>Ты просто пересказываешь документацию.
>А меня интересовала консультация человека, который понял, почему так происходит.
скорее обьяснил не очень внятно
появляется данный баг если значение $_SESSION['var'] === NULL
Код:
<?php
session_start();
var_dump($_SESSION['var']);
$_SESSION['var'] = NULL;
var_dump($_SESSION['var']);
$var = 'xxx';
var_dump($_SESSION['var']);
 

Фанат

oncle terrible
Команда форума
объяснил не очень внятно или понял не очень внятно? ;-)
а этот код вызовет ошибку, или нет?
$_SESSION['login']=NULL;
$login=$_GET['login'];
 

DYPA

Настоящая dypa (c)
через пару часов php4 умрет, поэтому запостил изменение функциональности
http://bugs.php.net/43722
 

DYPA

Настоящая dypa (c)
вызовет(но если session_start(); ...), на пальцах это выглядит так, php проверяет что переменная не существует (NULL), когда $login = происходит срабатывание бага, те происходит следующее
PHP:
$_SESSION['login'] = NULL;
$login = $_GET['login'];
//isset под вопросом, нада разбираться с тем что такое си ;)
if (!isset($_SESSION['login']) || $_SESSION['login'] === NULL)
{
    $_SESSION['login'] = $login;
    trigger_error("Your script possibly relies...", E_WARNING);
}
 

Фанат

oncle terrible
Команда форума
скрипт ошибку не вызовет, если нотис выдаст =)

а иссет сработает, как надо. у меня таблица сравнений два дня открытая висела.
 

DYPA

Настоящая dypa (c)
>скрипт ошибку не вызовет, если нотис выдаст =)
для меня и нойтис уже ошибка, причем страшная, а в данном случае вообще warning )

ps парсер бб кода лажается на теге php (<img src="images/smilies/wink.gif" border="0" alt="">)
pss уходим какжется в офтопик...
 

Фанат

oncle terrible
Команда форума
Да ладно. Для этого форума это далеко не самый жесткий оффтопик =)

Я хотел сказать, что обсуждаемой ошибки не будет. если переменной гетом не будет
можно и без нотиса.
$_SESSION['login'] = NULL;
$login = NULL;
 

DYPA

Настоящая dypa (c)
>Я хотел сказать, что обсуждаемой ошибки не будет. если переменной гетом не будет
я придерживался начального условия:
>обращение: ttt.php?login=test
 
Сверху