- URL: https://www.laruence.com/en/2009/07/13/976.html
- Please include attribution when republishing.
The full warning text is as follows:
PHP Warning: Unknown: 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. in Unknown on
There are many solutions to this problem online, but they are all answers given without understanding the why. So what is the real cause, and how do you solve it?
First, remember this: starting with PHP 4.2, register_globals defaulted to OFF.
After 4.2.3, to stay compatible with the old behaviour, PHP introduced bug_compat_42. When this option is enabled (it is by default), PHP allows variables in SESSION to be used automatically as global variables. It's just that if bug_compat_warn is also enabled, the use of this feature is reported.
Look at a piece of code:
<?php session_start(); var_dump($_SESSION); $name = 'laruence'; $_SESSION['name'] = null; ?>
The code above, with bug_compat_42 enabled and register_globals off, produces the following output across two page refreshes:
//first time:
array(0) {}
//second time
array(1) { ["a"]=> string(8) "laruence" }
Why isn't the second time NULL? Because with bug_compat_42 enabled, PHP treats the variable a as a reference to $_SESSION['a'], and on session_close it writes the value of a back.
During this process, if bug_compat_warn is enabled, the warning at the start of this article is thrown.
So, that it is.
So what exactly are the conditions under which it gives the warning? Once we know them, we can avoid this warning.
In PHPSRC/ext/session/session.c, we have all the answers we want:
static void php_session_save_current_state(TSRMLS_D) /* {{{ */
{
int ret = FAILURE;
IF_SESSION_VARS() {
//if the Session array exists
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) { //variable is null
if (migrate_global(ht, &pos TSRMLS_CC)) {//write the variable back
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 ..........");
//rest omitted
So, as you can see, you won't see this warning if bug_compat_42 is off (this feature is rarely used these days, and enabling it can sometimes cause more confusion), or if bug_compat_warn is off, or if register_globals is enabled.
In addition, with bug_compat_42 enabled you may also run into the following NOTICE..
PHP Notice: Unknown: The session bug compatibility code will not try to locate the global variable $324324 due to its numeric nature in Unknown on line 0
This is a warning that can be triggered when you use a numeric index in $_SESSION.
Be First to Comment