Hex 发表于 2013-7-16 16:40:59

CodeIgniter的那些坑(三)

作者:线筝
原文:http://h5b.net/codeigniter-global-value-lose/


曾经因为一个业务需求,需要在CodeIgniter的CodeIgniter/index.php的入口文件中加入这样一句代码

$GLOBALS['SERVERINDEX'] = 1;

用来让同一个套代码,区分不同的服务器环境,在开发的时候万事OK,但是放到线上,却总在php_error.log中发现这么一个notice

PHP Notice:Undefined index: SERVERINDEX in 脚本名

郁闷了好几天,最后终于发现了原因,在CodeIgniter/system/core/Input.php中存在这么一段代码

<?phpif ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
*
* @package                CodeIgniter
* @author                ExpressionEngine Dev Team
* @copyright        Copyright (c) 2008 - 2011, EllisLab, Inc.
* @license                http://codeigniter.com/user_guide/license.html
* @link                http://codeigniter.com
* @since                Version 1.0
* @filesource
*/

// ------------------------------------------------------------------------

/**
* Input Class
*
* Pre-processes global input data for security
*
* @package                CodeIgniter
* @subpackage        Libraries
* @category        Input
* @author                ExpressionEngine Dev Team
* @link                http://codeigniter.com/user_guide/libraries/input.html
*/
class CI_Input {

        public function __construct()
        {
                log_message('debug', "Input Class Initialized");

                $this->_allow_get_array        = (config_item('allow_get_array') === TRUE);
                $this->_enable_xss                = (config_item('global_xss_filtering') === TRUE);
                $this->_enable_csrf                = (config_item('csrf_protection') === TRUE);

                global $SEC;
                $this->security =& $SEC;

                // Do we need the UTF-8 class?
                if (UTF8_ENABLED === TRUE)
                {
                        global $UNI;
                        $this->uni =& $UNI;
                }

                // Sanitize global arrays
                $this->_sanitize_globals();
        }


        // --------------------------------------------------------------------

        /**
        * Sanitize Globals
        *
        * This function does the following:
        *
        * Unsets $_GET data (if query strings are not enabled)
        *
        * Unsets all globals if register_globals is enabled
        *
        * Standardizes newline characters to \n
        *
        * @access        private
        * @return        void
        */
        function _sanitize_globals()
        {
                // It would be "wrong" to unset any of these GLOBALS.
                $protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST',
                                                        '_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA',
                                                        'system_folder', 'application_folder', 'BM', 'EXT',
                                                        'CFG', 'URI', 'RTR', 'OUT', 'IN');

                // Unset globals for securiy.
                // This is effectively the same as register_globals = off
                foreach (array($_GET, $_POST, $_COOKIE) as $global)
                {
                        if ( ! is_array($global))
                        {
                                if ( ! in_array($global, $protected))
                                {
                                        global $$global;
                                        $$global = NULL;
                                }
                        }
                        else
                        {
                                foreach ($global as $key => $val)
                                {
                                        if ( ! in_array($key, $protected))
                                        {
                                                global $$key;
                                                $$key = NULL;
                                        }
                                }
                        }
                }

                // Is $_GET data allowed? If not we'll set the $_GET to an empty array
                if ($this->_allow_get_array == FALSE)
                {
                        $_GET = array();
                }
                else
                {
                        if (is_array($_GET) AND count($_GET) > 0)
                        {
                                foreach ($_GET as $key => $val)
                                {
                                        $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
                                }
                        }
                }

                // Clean $_POST Data
                if (is_array($_POST) AND count($_POST) > 0)
                {
                        foreach ($_POST as $key => $val)
                        {
                                $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
                        }
                }

                // Clean $_COOKIE Data
                if (is_array($_COOKIE) AND count($_COOKIE) > 0)
                {
                        // Also get rid of specially treated cookies that might be set by a server
                        // or silly application, that are of no use to a CI application anyway
                        // but that when present will trip our 'Disallowed Key Characters' alarm
                        // http://www.ietf.org/rfc/rfc2109.txt
                        // note that the key names below are single quoted strings, and are not PHP variables
                        unset($_COOKIE['$Version']);
                        unset($_COOKIE['$Path']);
                        unset($_COOKIE['$Domain']);

                        foreach ($_COOKIE as $key => $val)
                        {
                                $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
                        }
                }

                // Sanitize PHP_SELF
                $_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);


                // CSRF Protection check on HTTP requests
                if ($this->_enable_csrf == TRUE && ! $this->is_cli_request())
                {
                        $this->security->csrf_verify();
                }

                log_message('debug', "Global POST and COOKIE data sanitized");
        }

}

/* End of file Input.php */
/* Location: ./system/core/Input.php */

这个方法会过滤$global中的值,而且还是有条件的过滤,所以就产生了我们的问题,所以要在protected中加入你需要的值SERVERINDEX。

qingbofish 发表于 2014-5-23 21:32:44

都被踩过的坑

qingbofish 发表于 2014-5-23 21:33:17

都被踩过的坑
页: [1]
查看完整版本: CodeIgniter的那些坑(三)