CI架構源碼翻閱-Input.php

來源:互聯網
上載者:User
CI架構源碼閱讀---------Input.php
_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);// 清除globals變數,在開啟了globals_register的情況下,相當於關閉了此配置。// 開啟一道 安全防護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();}// --------------------------------/** * Fetch from array * 從$array擷取值,如果設定了xss_clean 那麼進行過濾  * This is a helper function to retrieve 檢索 values from global arrays * 這是一個協助函數用來從全域數組中檢索 * * @accessprivate * @paramarray * @paramstring * @parambool * @returnstring */function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE){if ( ! isset($array[$index])){return FALSE;}if ($xss_clean === TRUE){return $this->security->xss_clean($array[$index]);}return $array[$index];}// --------------------------------/*** Fetch an item from the GET array* 擷取過濾後的GET數組* @accesspublic* @paramstring* @parambool* @returnstring*/function get($index = NULL, $xss_clean = FALSE){// Check if a field has been provided// 檢查是否一個欄位已經被提供if ($index === NULL AND ! empty($_GET)){$get = array();// loop through the full _GET array// 遍曆_GET數組foreach (array_keys($_GET) as $key){$get[$key] = $this->_fetch_from_array($_GET, $key, $xss_clean);}return $get;}return $this->_fetch_from_array($_GET, $index, $xss_clean);}// --------------------------------/*** Fetch an item from the POST array* 擷取過濾後的$_POST值* @accesspublic* @paramstring* @parambool* @returnstring*/function post($index = NULL, $xss_clean = FALSE){// Check if a field has been providedif ($index === NULL AND ! empty($_POST)){$post = array();// Loop through the full _POST array and return itforeach (array_keys($_POST) as $key){$post[$key] = $this->_fetch_from_array($_POST, $key, $xss_clean);}return $post;}return $this->_fetch_from_array($_POST, $index, $xss_clean);}// --------------------------------/*** Fetch an item from either the GET array or the POST* 從get和post中擷取值, post優先* @accesspublic* @paramstringThe index key* @paramboolXSS cleaning* @returnstring*/function get_post($index = '', $xss_clean = FALSE){if ( ! isset($_POST[$index]) ){return $this->get($index, $xss_clean);}else{return $this->post($index, $xss_clean);}}// --------------------------------/*** Fetch an item from the COOKIE array* 返回過濾後的COOKIE值* @accesspublic* @paramstring* @parambool* @returnstring*/function cookie($index = '', $xss_clean = FALSE){return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);}// ------------------------------------/*** Set cookie** Accepts six parameter, or you can submit an associative* array in the first parameter containing all the values.* 接收6個參數或者接收一個關聯陣列裡麵包含所有的值* @accesspublic* @parammixed* @paramstringthe value of the cookie* @paramstringthe number of seconds until expiration* @paramstringthe cookie domain.  Usually:  .yourdomain.com* @paramstringthe cookie path* @paramstringthe cookie prefix* @parambooltrue makes the cookie secure* @returnvoid*/function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE){// 如果第一個值是數組 將數組中的值分別賦值給留個參數if (is_array($name)){// always leave 'name' in last place, as the loop will break otherwise, due to $$itemforeach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'name') as $item){if (isset($name[$item])){$$item = $name[$item];}}}// 如果某個參數為預設值但是config.php中的配置不是預設值// 則使用config.php中的配置值if ($prefix == '' AND config_item('cookie_prefix') != ''){$prefix = config_item('cookie_prefix');}if ($domain == '' AND config_item('cookie_domain') != ''){$domain = config_item('cookie_domain');}if ($path == '/' AND config_item('cookie_path') != '/'){$path = config_item('cookie_path');}if ($secure == FALSE AND config_item('cookie_secure') != FALSE){$secure = config_item('cookie_secure');}if ( ! is_numeric($expire)){$expire = time() - 86500;}else{$expire = ($expire > 0) ? time() + $expire : 0;}setcookie($prefix.$name, $value, $expire, $path, $domain, $secure);}// --------------------------------/*** Fetch an item from the SERVER array* 返回過濾後的$_SERVER值* @accesspublic* @paramstring* @parambool* @returnstring*/function server($index = '', $xss_clean = FALSE){return $this->_fetch_from_array($_SERVER, $index, $xss_clean);}// --------------------------------/*** Fetch the IP Address* 返回目前使用者的IP。如果IP地址無效,返回0.0.0.0的IP:* @returnstring*/public function ip_address(){// 如果已經有了ip_address 則返回if ($this->ip_address !== FALSE){return $this->ip_address;}$proxy_ips = config_item('proxy_ips');if ( ! empty($proxy_ips)){$proxy_ips = explode(',', str_replace(' ', '', $proxy_ips));foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP') as $header){if (($spoof = $this->server($header)) !== FALSE){// Some proxies typically list the whole chain of IP// addresses through which the client has reached us.// e.g. client_ip, proxy_ip1, proxy_ip2, etc.if (strpos($spoof, ',') !== FALSE){$spoof = explode(',', $spoof, 2);$spoof = $spoof[0];}if ( ! $this->valid_ip($spoof)){$spoof = FALSE;}else{break;}}}$this->ip_address = ($spoof !== FALSE && in_array($_SERVER['REMOTE_ADDR'], $proxy_ips, TRUE))? $spoof : $_SERVER['REMOTE_ADDR'];}else{$this->ip_address = $_SERVER['REMOTE_ADDR'];}if ( ! $this->valid_ip($this->ip_address)){$this->ip_address = '0.0.0.0';}return $this->ip_address;}// --------------------------------/*** Validate IP Address* 測試輸入的IP地址是不是有效,返回布爾值TRUE或者FALSE。 * 注意:$this->input->ip_address()自動化的測試輸入的IP地址本身格式是不是有效。* @accesspublic* @paramstring* @paramstringipv4 or ipv6* @returnbool*/public function valid_ip($ip, $which = ''){$which = strtolower($which);// First check if filter_var is availableif (is_callable('filter_var')){switch ($which) {case 'ipv4':$flag = FILTER_FLAG_IPV4;break;case 'ipv6':$flag = FILTER_FLAG_IPV6;break;default:$flag = '';break;}return (bool) filter_var($ip, FILTER_VALIDATE_IP, $flag);}if ($which !== 'ipv6' && $which !== 'ipv4'){if (strpos($ip, ':') !== FALSE){$which = 'ipv6';}elseif (strpos($ip, '.') !== FALSE){$which = 'ipv4';}else{return FALSE;}}$func = '_valid_'.$which;return $this->$func($ip);}// --------------------------------/*** Validate IPv4 Address* 驗證ipv4地址* Updated version suggested by Geert De Deckere** @accessprotected* @paramstring* @returnbool*/protected function _valid_ipv4($ip){$ip_segments = explode('.', $ip);// Always 4 segments neededif (count($ip_segments) !== 4){return FALSE;}// IP can not start with 0if ($ip_segments[0][0] == '0'){return FALSE;}// Check each segmentforeach ($ip_segments as $segment){// IP segments must be digits and can not be// longer than 3 digits or greater then 255if ($segment == '' OR preg_match("/[^0-9]/", $segment) OR $segment > 255 OR strlen($segment) > 3){return FALSE;}}return TRUE;}// --------------------------------/*** Validate IPv6 Address* 驗證ipv6地址* @accessprotected* @paramstring* @returnbool*/protected function _valid_ipv6($str){// 8 groups, separated by :// 0-ffff per group// one set of consecutive 0 groups can be collapsed to ::$groups = 8;$collapsed = FALSE;$chunks = array_filter(preg_split('/(:{1,2})/', $str, NULL, PREG_SPLIT_DELIM_CAPTURE));// Rule out easy nonsenseif (current($chunks) == ':' OR end($chunks) == ':'){return FALSE;}// PHP supports IPv4-mapped IPv6 addresses, so we'll expect those as wellif (strpos(end($chunks), '.') !== FALSE){$ipv4 = array_pop($chunks);if ( ! $this->_valid_ipv4($ipv4)){return FALSE;}$groups--;}while ($seg = array_pop($chunks)){if ($seg[0] == ':'){if (--$groups == 0){return FALSE;// too many groups}if (strlen($seg) > 2){return FALSE;// long separator}if ($seg == '::'){if ($collapsed){return FALSE;// multiple collapsed}$collapsed = TRUE;}}elseif (preg_match("/[^0-9a-f]/i", $seg) OR strlen($seg) > 4){return FALSE; // invalid segment}}return $collapsed OR $groups == 1;}// --------------------------------/*** User Agent* 返回目前使用者正在使用的瀏覽器的user agent資訊。 如果不能得到資料,返回FALSE。* 一般user_agent為空白的時候被認定為手機訪問,或者curl的抓取,或則會蜘蛛抓取* @accesspublic* @returnstring*/function user_agent(){if ($this->user_agent !== FALSE){return $this->user_agent;}$this->user_agent = ( ! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT'];return $this->user_agent;}// --------------------------------/*** Sanitize Globals* 清理全域數組* This function does the following:* 這個函數做了下面的操作:* Unsets $_GET data (if query strings are not enabled)* 銷毀$_GET (如果query strings 沒有開啟)* Unsets all globals if register_globals is enabled* 銷毀所有全域數組如果register_globals開啟** Standardizes newline characters to \n* 標準化分行符號\n* @accessprivate* @returnvoid*/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// 這樣的效果和register_globals是相同的        // 經過下面處理後,所有的非保護的全域變數將被刪除掉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// 是否允許$_GET資料? 如果不允許的話,設定$_GET為空白數組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// 過濾$_POST 數組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// 過濾$_COOKIE數組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 variablesunset($_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// CSRF保護檢測http請求if ($this->_enable_csrf == TRUE && ! $this->is_cli_request()){$this->security->csrf_verify();}log_message('debug', "Global POST and COOKIE data sanitized");}// --------------------------------/*** Clean Input Data* 過濾input資料* This is a helper function. It escapes data and* standardizes newline characters to \n** @accessprivate* @paramstring* @returnstring*/function _clean_input_data($str){if (is_array($str)){$new_array = array();foreach ($str as $key => $val){$new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);}return $new_array;}/* We strip slashes if magic quotes is on to keep things consistent如果小於PHP5.4版本,並且get_magic_quotes_gpc開啟了,則去掉斜線。   NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and   it will probably not exist in future versions at all。   注意:在PHP5.4及之後版本,get_magic_quotes_gpc()將總是返回0,   在後續版本中可能會移除該特性*/if ( ! is_php('5.4') && get_magic_quotes_gpc()){$str = stripslashes($str);}// Clean UTF-8 if supported 如果支援清理utf8if (UTF8_ENABLED === TRUE){$str = $this->uni->clean_string($str);}// Remove control characters $str = remove_invisible_characters($str);// Should we filter the input data?if ($this->_enable_xss === TRUE){$str = $this->security->xss_clean($str);}// Standardize newlines if neededif ($this->_standardize_newlines == TRUE){if (strpos($str, "\r") !== FALSE){$str = str_replace(array("\r\n", "\r", "\r\n\n"), PHP_EOL, $str);}}return $str;}// --------------------------------/*** Clean Keys* 過濾索引值 * This is a helper function. To prevent malicious users* from trying to exploit keys we make sure that keys are* only named with alpha-numeric text and a few other items.** @accessprivate* @paramstring* @returnstring*/function _clean_input_keys($str){if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str)){exit('Disallowed Key Characters.');}// Clean UTF-8 if supportedif (UTF8_ENABLED === TRUE){$str = $this->uni->clean_string($str);}return $str;}// --------------------------------/** * Request Headers * 返回要求標頭(header)數組。 * In Apache, you can simply call apache_request_headers(), however for * people running other webservers the function is undefined. * * @parambool XSS cleaning * * @return array */public function request_headers($xss_clean = FALSE){// Look at Apache go!if (function_exists('apache_request_headers')){$headers = apache_request_headers();}else{$headers['Content-Type'] = (isset($_SERVER['CONTENT_TYPE'])) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE');foreach ($_SERVER as $key => $val){if (strncmp($key, 'HTTP_', 5) === 0){$headers[substr($key, 5)] = $this->_fetch_from_array($_SERVER, $key, $xss_clean);}}}// take SOME_HEADER and turn it into Some-Headerforeach ($headers as $key => $val){$key = str_replace('_', ' ', strtolower($key));$key = str_replace(' ', '-', ucwords($key));$this->headers[$key] = $val;}return $this->headers;}// --------------------------------/** * Get Request Header * 返回要求標頭(request header)數組中某一個元素的值 * Returns the value of a single member of the headers class member * * @param stringarray key for $this->headers * @parambooleanXSS Clean or not * @return mixedFALSE on failure, string on success */public function get_request_header($index, $xss_clean = FALSE){if (empty($this->headers)){$this->request_headers();}if ( ! isset($this->headers[$index])){return FALSE;}if ($xss_clean === TRUE){return $this->security->xss_clean($this->headers[$index]);}return $this->headers[$index];}// --------------------------------/** * Is ajax Request?  * 判斷是否為ajax請求 * Test to see if a request contains the HTTP_X_REQUESTED_WITH header * * @return boolean */public function is_ajax_request(){return ($this->server('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest');}// --------------------------------/** * Is cli Request? * 判斷是否來自cli請求 * Test to see if a request was made from the command line * * @return bool */public function is_cli_request(){return (php_sapi_name() === 'cli' OR defined('STDIN'));}}/* End of file Input.php *//* Location: ./system/core/Input.php */

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.