You are here: PHP Kernel Analytics> Main Web>PHPKernel>SessionWarning2009-07-13, Laruence

PHP Session的一个警告

警告全文如下:

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

关于这个问题, 网上有多种解决办法, 但都是不知所以然的答案, 那么真正的原因是什么呢, 怎么解决呢?

请首先记住这一点. 在PHP4.2开始, register_globals默认设置为了OFF.

然后,来看一段代码,

<?php
session_start();
$session['name'] = $name;
上面的代码, 在register_globals打开的情况下, $name就可能是来自POST或者GET的用户提交的用户名..

但是, 在register_globals关闭的情况下, Zend引擎发现$name为null, 那么它就会善意的警告你, 你是不是忘记了register_globals关闭的情况下依赖于一个全局变量了?

So, that it is~

那么, 它具体给出警告的条件是什么呢? 知道了这些条件, 我们就可以避免这个警告了,

在PHPSRC/ext/session/session.c中, 有我们想要的一切答案:

static void php_session_save_current_state(TSRMLS_D) /* {{{ */
{
        int ret = FAILURE;
        
        IF_SESSION_VARS() {
                //如果存在Session数组
                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) { //变量为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");
                                //后面省略	
                                

首先, 如果session.bug_compat_42是打开并且register_globals关闭的情况下.

然后,如果这个值是null[Z_TYPE_PP(val) == IS_NULL], 并且migrate_globals, migrate_golbals是在当前符号表中,查询是否有同名的变量(这个很重要);

最后, 如果bug_compat_warn也是打开的, 那么你就可以看到这个警告了.

接下来, 我们重现一个这个警告:

<?php
session_start(); 
$a = 'laruence' ; //在当前符号表插入一个同名变量
$_SESSION['a'] = null; //同名session变量,并且值为null
?> 
那么,在打开bug_compat_42,和bug_compat_warn,并且关闭register_globals的情况下, 你就可以看到这个警告了.

-- Main.Laruence - 2009-07-13

 
Topic revision: r1 - 2009-07-13 - 11:00:03 - Main.Laruence
 

TWIKI.NET
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Supported by Onemouse/风雪之隅 京ICP备09034578号
Ideas, requests, problems regarding PHP Kernel Analytics? Send feedback