文件位于system/core/common.php,是框架核心文件。
该文件中定义了一系列的函数,都是框架运行中经常需要用到的。下面逐一介绍。
is_php
1 /** 2 * Determines if the current version of PHP is equal to or greater than the supplied value 3 * 4 * @param string 5 * @return bool TRUE if the current version is $version or higher 6 */ 7 function is_php($version) 8 { 9 static $_is_php; 10 $version = (string) $version; 11 12 if ( ! isset($_is_php[$version])) 13 { 14 $_is_php[$version] = version_compare(PHP_VERSION, $version, '>='); 15 } 16 17 return $_is_php[$version]; 18 } 19 }
该函数用于进行php版本比较,如果运行的php版本大于等于输入的php版本参数,则返回true。这里建立了一个$is_php静态数组,把新版本参数比较的结果存在数组里,如果再有类似的版本参数传入,不用比较,直接返回结果。是一种空间换时间的做法。
is_really_writable
1 /** 2 * Tests for file writability 3 * 4 * is_writable() returns TRUE on Windows servers when you really can't write to 5 * the file, based on the read-only attribute. is_writable() is also unreliable 6 * on Unix servers if safe_mode is on. 7 * 8 * @link https://bugs.php.net/bug.php?id=54709 9 * @param string 10 * @return bool 11 */ 12 function is_really_writable($file) 13 { 14 // If we're on a Unix server with safe_mode off we call is_writable 15 //用DIRECTORY_SEPARATOR === '/'来判断是unix系统, 16 if (DIRECTORY_SEPARATOR === '/' && (is_php('5.4') OR ! ini_get('safe_mode'))) 17 { 18 return is_writable($file); 19 } 20 21 /* For Windows servers and safe_mode "on" installations we'll actually 22 * write a file then read it. Bah... 23 * 对于windows操作系统和安全模式的处理方法 24 */ 25 if (is_dir($file))//对于目录 26 { 27 $file = rtrim($file, '/').'/'.md5(mt_rand()); 28 if (($fp = @fopen($file, 'ab')) === FALSE) 29 { 30 return FALSE; 31 } 32 33 fclose($fp); 34 @chmod($file, 0777); 35 @unlink($file); 36 return TRUE; 37 } 38 elseif ( ! is_file($file) OR ($fp = @fopen($file, 'ab')) === FALSE)//对于文件 39 { 40 return FALSE; 41 } 42 43 fclose($fp); 44 return TRUE; 45 }
该函数用于判断文件或目录是否可写。
对于linux系统未使用安全模式的情况,直接调用php函数is_writable($file)即可。
对于windows系统和使用安全模式的linux系统则根据是文件夹还是文件采取不同的方式:文件夹是 在看是否可在里面新建一个可读写的文件;文件是看是否可读写打开。
&load_class
1 /** 2 * Class registry 3 * 4 * This function acts as a singleton. If the requested class does not 5 * exist it is instantiated and set to a static variable. If it has 6 * previously been instantiated the variable is returned. 7 * 8 * @param string the class name being requested 9 * @param string the directory where the class should be found 10 * @param mixed an optional argument to pass to the class constructor 11 * @return object 12 */ 13 function &load_class($class, $directory = 'libraries', $param = NULL) 14 { 15 static $_classes = array(); 16 17 // Does the class exist? If so, we're done... 18 if (isset($_classes[$class])) 19 { 20 return $_classes[$class]; 21 } 22 23 $name = FALSE; 24 25 // Look for the class first in the local application/libraries folder 26 // then in the native system/libraries folder 27 foreach (array(APPPATH, BASEPATH) as $path) 28 { 29 if (file_exists($path.$directory.'/'.$class.'.php')) 30 { 31 $name = 'CI_'.$class; 32 33 if (class_exists($name, FALSE) === FALSE) 34 { 35 require_once($path.$directory.'/'.$class.'.php'); 36 } 37 38 break; 39 } 40 } 41 42 // Is the request a class extension? If so we load it too 43 if (file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php')) 44 { 45 $name = config_item('subclass_prefix').$class; 46 47 if (class_exists($name, FALSE) === FALSE) 48 { 49 require_once(APPPATH.$directory.'/'.$name.'.php'); 50 } 51 } 52 53 // Did we find the class? 54 if ($name === FALSE) 55 { 56 // Note: We use exit() rather than show_error() in order to avoid a 57 // self-referencing loop with the Exceptions class 58 set_status_header(503); 59 echo 'Unable to locate the specified class: '.$class.'.php'; 60 exit(5); // EXIT_UNK_CLASS 61 } 62 63 // Keep track of what we just loaded 64 is_loaded($class); 65 66 $_classes[$class] = isset($param) 67 ? new $name($param) 68 : new $name(); 69 return $_classes[$class]; 70 } 71 }
该函数用于类的注册,核心函数。
这个函数维护一个单例模式,即如果请求注册的类$class已经被实例化过了,则把保存的实例化对象返回,如果没有实例化过,就实例化该类。这个做法避免新建大量的对象,减少内存消耗,也减少了框架使用对象的维护成本,避免使用的混乱。
在搜索类文件的时候,既会搜索系统的类文件,也会搜索用户自定义的类文件。用户自定义类名需要定义统一的前缀,这个前缀在application/config/config.php文件的subclass_prefix变量中定义。
该函数前面有一个&,表明是引用传递返回值。即返回的对象以后发生变化的时候,在这个函数中定义的$_classes[$class]也会发生变化。参考知乎上的解释。
&is_loaded($class = '')
/** * Keeps track of which libraries have been loaded. This function is * called by the load_class() function above * * @param string * @return array */ function &is_loaded($class = '') { static $_is_loaded = array(); if ($class !== '') { $_is_loaded[strtolower($class)] = $class; } return $_is_loaded; }
该函数可以获取已经在load_class函数中注册的类名数组,也可以往 类名数组中添加一个已经注册的类名。使用引用传递返回值。
&get_config(Array $replace = array())
1 /** 2 * Loads the main config.php file 3 * 4 * This function lets us grab the config file even if the Config class 5 * hasn't been instantiated yet 6 * 7 * @param array 8 * @return array 9 */ 10 function &get_config(Array $replace = array()) 11 { 12 static $config; 13 14 if (empty($config)) 15 { 16 $file_path = APPPATH.'config/config.php'; 17 $found = FALSE; 18 if (file_exists($file_path)) 19 { 20 $found = TRUE; 21 require($file_path); 22 } 23 24 // Is the config file in the environment folder? 25 if (file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php')) 26 { 27 require($file_path); 28 } 29 elseif ( ! $found) 30 { 31 set_status_header(503); 32 echo 'The configuration file does not exist.'; 33 exit(3); // EXIT_CONFIG 34 } 35 36 // Does the $config array exist in the file? 37 if ( ! isset($config) OR ! is_array($config)) 38 { 39 set_status_header(503); 40 echo 'Your config file does not appear to be formatted correctly.'; 41 exit(3); // EXIT_CONFIG 42 } 43 } 44 45 // Are any values being dynamically added or replaced? 46 foreach ($replace as $key => $val) 47 { 48 $config[$key] = $val; 49 } 50 51 return $config; 52 } 53 }
View Code
该函数用来加载application/config/config.php中的$config数组变量。当然,如果存在,也加载用户根据环境定义的config.php文件。
config.php文件中定义了一些系统和应用程序的设置,包括使用何种编码,是否采用csrf,自定义的类的类名前缀等等。
同时,使用该函数通过$replace也可以追加一些设置。
该函数使用静态局部变量数组$config来存储。使用引用传递返回值。
config_item($item)
1 /** 2 * Returns the specified config item 3 * 4 * @param string 5 * @return mixed 6 */ 7 function config_item($item) 8 { 9 static $_config; 10 11 if (empty($_config)) 12 { 13 // references cannot be directly assigned to static variables, so we use an array 14 $_config[0] =& get_config(); 15 } 16 17 return isset($_config[0][$item]) ? $_config[0][$item] : NULL; 18 }
该函数用于获取某一个具体的在get_config()中定义的$config数组的值。
&get_mimes()
1 /** 2 * Returns the MIME types array from config/mimes.php 3 * 4 * @return array 5 */ 6 function &get_mimes() 7 { 8 static $_mimes; 9 10 if (empty($_mimes)) 11 { 12 $_mimes = file_exists(APPPATH.'config/mimes.php') 13 ? include(APPPATH.'config/mimes.php') 14 : array(); 15 16 if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')) 17 { 18 $_mimes = array_merge($_mimes, include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')); 19 } 20 } 21 22 return $_mimes; 23 }
该函数用于获取在application/config/mimes.php中定义的mime类型数组。主要用于文件上传时候的检测。
is_https()
1 /** 2 * Is HTTPS? 3 * 4 * Determines if the application is accessed via an encrypted 5 * (HTTPS) connection. 6 * 7 * @return bool 8 */ 9 function is_https() 10 { 11 if ( ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') 12 { 13 return TRUE; 14 } 15 elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') 16 { 17 return TRUE; 18 } 19 elseif ( ! empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') 20 { 21 return TRUE; 22 } 23 24 return FALSE; 25 }
该函数判断请求是否是http请求。
is_cli()
1 /** 2 * Is CLI? 3 * 4 * Test to see if a request was made from the command line. 5 * 6 * @return bool 7 */ 8 function is_cli() 9 { 10 return (PHP_SAPI === 'cli' OR defined('STDIN')); 11 }
该函数用于判断请求是否是命令行方式。
show_error($message, $status_code = 500, $heading = 'An Error Was Encountered')
1 /** 2 * Error Handler 3 * 4 * This function lets us invoke the exception class and 5 * display errors using the standard error template located 6 * in application/views/errors/error_general.php 7 * This function will send the error page directly to the 8 * browser and exit. 9 * 10 * @param string 11 * @param int 12 * @param string 13 * @return void 14 */ 15 function show_error($message, $status_code = 500, $heading = 'An Error Was Encountered') 16 { 17 $status_code = abs($status_code);//取绝对值 18 if ($status_code < 100) 19 { 20 $exit_status = $status_code + 9; // 9 is EXIT__AUTO_MIN 21 $status_code = 500; 22 } 23 else 24 { 25 $exit_status = 1; // EXIT_ERROR 26 } 27 28 $_error =& load_class('Exceptions', 'core'); 29 echo $_error->show_error($heading, $message, 'error_general', $status_code); 30 exit($exit_status); 31 }
该函数用于主动显示一个错误提示给用户,无论是命令行模式还是浏览器显示。调用的是Exceptions类的show_error方法。
show_404($page = '', $log_error = TRUE)
1 /** 2 * 404 Page Handler 3 * 4 * This function is similar to the show_error() function above 5 * However, instead of the standard error template it displays 6 * 404 errors. 7 * 8 * @param string 9 * @param bool 10 * @return void 11 */ 12 function show_404($page = '', $log_error = TRUE) 13 { 14 $_error =& load_class('Exceptions', 'core'); 15 $_error->show_404($page, $log_error); 16 exit(4); // EXIT_UNKNOWN_FILE 17 }
该函数用于主动显示一个404错误给用户,无论是命令行模式还是浏览器显示。调用的是Exceptions类的show_404方法。
log_message($level, $message)
1 /** 2 * Error Logging Interface 3 * 4 * We use this as a simple mechanism to access the logging 5 * class and send messages to be logged. 6 * 7 * @param string the error level: 'error', 'debug' or 'info' 8 * @param string the error message 9 * @return void 10 */ 11 function log_message($level, $message) 12 { 13 static $_log; 14 15 if ($_log === NULL) 16 { 17 // references cannot be directly assigned to static variables, so we use an array 18 $_log[0] =& load_class('Log', 'core'); 19 } 20 21 $_log[0]->write_log($level, $message); 22 }
该函数用于记录日志。常用的函数。日志分Error,Debug,Info三个级别。调用的是Log类的write_log方法。
set_status_header($code = 200, $text = '')
1 /** 2 * Set HTTP Status Header 3 * 4 * @param int the status code 5 * @param string 6 * @return void 7 */ 8 function set_status_header($code = 200, $text = '') 9 { 10 if (is_cli()) 11 { 12 return; 13 } 14 15 if (empty($code) OR ! is_numeric($code)) 16 { 17 show_error('Status codes must be numeric', 500); 18 } 19 20 if (empty($text)) 21 { 22 is_int($code) OR $code = (int) $code; 23 $stati = array( 24 100 => 'Continue', 25 101 => 'Switching Protocols', 26 27 200 => 'OK', 28 201 => 'Created', 29 202 => 'Accepted', 30 203 => 'Non-Authoritative Information', 31 204 => 'No Content', 32 205 => 'Reset Content', 33 206 => 'Partial Content', 34 35 300 => 'Multiple Choices', 36 301 => 'Moved Permanently', 37 302 => 'Found', 38 303 => 'See Other', 39 304 => 'Not Modified', 40 305 => 'Use Proxy', 41 307 => 'Temporary Redirect', 42 43 400 => 'Bad Request', 44 401 => 'Unauthorized', 45 402 => 'Payment Required', 46 403 => 'Forbidden', 47 404 => 'Not Found', 48 405 => 'Method Not Allowed', 49 406 => 'Not Acceptable', 50 407 => 'Proxy Authentication Required', 51 408 => 'Request Timeout', 52 409 => 'Conflict', 53 410 => 'Gone', 54 411 => 'Length Required', 55 412 => 'Precondition Failed', 56 413 => 'Request Entity Too Large', 57 414 => 'Request-URI Too Long', 58 415 => 'Unsupported Media Type', 59 416 => 'Requested Range Not Satisfiable', 60 417 => 'Expectation Failed', 61 422 => 'Unprocessable Entity', 62 426 => 'Upgrade Required', 63 428 => 'Precondition Required', 64 429 => 'Too Many Requests', 65 431 => 'Request Header Fields Too Large', 66 67 500 => 'Internal Server Error', 68 501 => 'Not Implemented', 69 502 => 'Bad Gateway', 70 503 => 'Service Unavailable', 71 504 => 'Gateway Timeout', 72 505 => 'HTTP Version Not Supported', 73 511 => 'Network Authentication Required', 74 ); 75 76 if (isset($stati[$code])) 77 { 78 $text = $stati[$code]; 79 } 80 else 81 { 82 show_error('No status text available. Please check your status code number or supply your own message text.', 500); 83 } 84 } 85 86 if (strpos(PHP_SAPI, 'cgi') === 0) 87 { 88 header('Status: '.$code.' '.$text, TRUE); 89 return; 90 } 91 92 $server_protocol = (isset($_SERVER['SERVER_PROTOCOL']) && in_array($_SERVER['SERVER_PROTOCOL'], array('HTTP/1.0', 'HTTP/1.1', 'HTTP/2'), TRUE)) 93 ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'; 94 header($server_protocol.' '.$code.' '.$text, TRUE, $code); 95 }
手动设置返回的http头,如果设置的是“500”。那么浏览器解析的Status Code就是500。
_error_handler($severity, $message, $filepath, $line)
1 /** 2 * Error Handler 3 * 4 * This is the custom error handler that is declared at the (relative) 5 * top of CodeIgniter.php. The main reason we use this is to permit 6 * PHP errors to be logged in our own log files since the user may 7 * not have access to server logs. Since this function effectively 8 * intercepts PHP errors, however, we also need to display errors 9 * based on the current error_reporting level. 10 * We do that with the use of a PHP error template. 11 * 12 * @param int $severity 13 * @param string $message 14 * @param string $filepath 15 * @param int $line 16 * @return void 17 */ 18 function _error_handler($severity, $message, $filepath, $line) 19 { 20 $is_error = (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity); 21 22 // When an error occurred, set the status header to '500 Internal Server Error' 23 // to indicate to the client something went wrong. 24 // This can't be done within the $_error->show_php_error method because 25 // it is only called when the display_errors flag is set (which isn't usually 26 // the case in a production environment) or when errors are ignored because 27 // they are above the error_reporting threshold. 28 if ($is_error) 29 { 30 set_status_header(500); 31 } 32 33 // Should we ignore the error? We'll get the current error_reporting 34 // level and add its bits with the severity bits to find out. 35 if (($severity & error_reporting()) !== $severity) 36 { 37 return; 38 } 39 40 $_error =& load_class('Exceptions', 'core'); 41 $_error->log_exception($severity, $message, $filepath, $line); 42 43 // Should we display the error? 44 if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors'))) 45 { 46 $_error->show_php_error($severity, $message, $filepath, $line); 47 } 48 49 // If the error is fatal, the execution of the script should be stopped because 50 // errors can't be recovered from. Halting the script conforms with PHP's 51 // default error handling. See http://www.php.net/manual/en/errorfunc.constants.php 52 if ($is_error) 53 { 54 exit(1); // EXIT_ERROR 55 } 56 }
该函数是在CodeIgniter.php中使用set_error_handler设置的用户自定义错误处理函数。该函数用于处理脚本中出现的错误。值得说明的是,以下级别的错误不能由用户定义的函数来处理: E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING。所以即使不小心进入了这个方法,也需要屏蔽掉。
对于在函数前加了@屏蔽warning的函数,也会进入这个方法。但是它的error_reporting()返回值是0,而不管系统设置的是什么。可以由此来判断直接返回,不做处理。
$severity包含了错误的级别,是一个 integer。
调用Exceptions类的show_php_error方法。
_exception_handler($exception)
1 /** 2 * Exception Handler 3 * 4 * Sends uncaught exceptions to the logger and displays them 5 * only if display_errors is On so that they don't show up in 6 * production environments. 7 * 8 * @param Exception $exception 9 * @return void 10 */ 11 function _exception_handler($exception) 12 { 13 $_error =& load_class('Exceptions', 'core'); 14 $_error->log_exception('error', 'Exception: '.$exception->getMessage(), $exception->getFile(), $exception->getLine()); 15 16 is_cli() OR set_status_header(500); 17 // Should we display the error? 18 if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors'))) 19 { 20 $_error->show_exception($exception); 21 } 22 23 exit(1); // EXIT_ERROR 24 }
该函数是在CodeIgniter.php中使用set_exception_handler设置的用户自定义异常处理函数。该函数是记录异常到日志中,并且展示给用户看到该异常。
set_error_handler和set_exception_handler的不同参见网上资料。
_shutdown_handler()
1 /** 2 * Shutdown Handler 3 * 4 * This is the shutdown handler that is declared at the top 5 * of CodeIgniter.php. The main reason we use this is to simulate 6 * a complete custom exception handler. 7 * 8 * E_STRICT is purposively neglected because such events may have 9 * been caught. Duplication or none? None is preferred for now. 10 * 11 * @link http://insomanic.me.uk/post/229851073/php-trick-catching-fatal-errors-e-error-with-a 12 * @return void 13 */ 14 function _shutdown_handler() 15 { 16 $last_error = error_get_last(); 17 if (isset($last_error) && 18 ($last_error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING))) 19 { 20 _error_handler($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']); 21 } 22 }
该函数是在CodeIgniter.php中使用register_shutdown_function 注册的会在php中止时执行的函数。
remove_invisible_characters($str, $url_encoded = TRUE)
1 /** 2 * Remove Invisible Characters 3 * 4 * This prevents sandwiching null characters 5 * between ascii characters, like Java\0script. 6 * 7 * @param string 8 * @param bool 9 * @return string 10 */ 11 function remove_invisible_characters($str, $url_encoded = TRUE) 12 { 13 $non_displayables = array(); 14 15 // every control character except newline (dec 10), 16 // carriage return (dec 13) and horizontal tab (dec 09) 17 if ($url_encoded) 18 { 19 $non_displayables[] = '/%0[0-8bcef]/i'; // url encoded 00-08, 11, 12, 14, 15 20 $non_displayables[] = '/%1[0-9a-f]/i'; // url encoded 16-31 21 $non_displayables[] = '/%7f/i'; // url encoded 127 22 } 23 24 $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127 25 26 do 27 { 28 $str = preg_replace($non_displayables, '', $str, -1, $count); 29 } 30 while ($count); 31 32 return $str; 33 }
该函数用于清除字符串中的不可见字符。 $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; 会匹配ascII中00-08, 11, 12, 14-31, 127的字符,这些字符都是不可见的。参见ascII字符表。
html_escape($var, $double_encode = TRUE)
1 /** 2 * Returns HTML escaped variable. 3 * 4 * @param mixed $var The input string or array of strings to be escaped. 5 * @param bool $double_encode $double_encode set to FALSE prevents escaping twice. 6 * @return mixed The escaped string or array of strings as a result. 7 */ 8 function html_escape($var, $double_encode = TRUE) 9 { 10 if (empty($var)) 11 { 12 return $var; 13 } 14 15 if (is_array($var)) 16 { 17 foreach (array_keys($var) as $key) 18 { 19 $var[$key] = html_escape($var[$key], $double_encode); 20 } 21 22 return $var; 23 } 24 25 return htmlspecialchars($var, ENT_QUOTES, config_item('charset'), $double_encode); 26 }
该函数用于将字符串或者字符串数组转换为html实体。
_stringify_attributes($attributes, $js = FALSE)
1 /** 2 * Stringify attributes for use in HTML tags. 3 * 4 * Helper function used to convert a string, array, or object 5 * of attributes to a string. 6 * 7 * @param mixed string, array, object 8 * @param bool 9 * @return string 10 */ 11 function _stringify_attributes($attributes, $js = FALSE) 12 { 13 $atts = NULL; 14 15 if (empty($attributes)) 16 { 17 return $atts; 18 } 19 20 if (is_string($attributes)) 21 { 22 return ' '.$attributes; 23 } 24 25 $attributes = (array) $attributes; 26 27 foreach ($attributes as $key => $val) 28 { 29 $atts .= ($js) ? $key.'='.$val.',' : ' '.$key.'="'.$val.'"'; 30 } 31 32 return rtrim($atts, ','); 33 }
View Code
将一个字符串属性,数组属性或者对象属性转换为一个字符串。主要用于在显示html页面的时候使用。
function_usable($function_name)
1 /** 2 * Function usable 3 * 4 * Executes a function_exists() check, and if the Suhosin PHP 5 * extension is loaded - checks whether the function that is 6 * checked might be disabled in there as well. 7 * 8 * This is useful as function_exists() will return FALSE for 9 * functions disabled via the *disable_functions* php.ini 10 * setting, but not for *suhosin.executor.func.blacklist* and 11 * *suhosin.executor.disable_eval*. These settings will just 12 * terminate script execution if a disabled function is executed. 13 * 14 * The above described behavior turned out to be a bug in Suhosin, 15 * but even though a fix was committed for 0.9.34 on 2012-02-12, 16 * that version is yet to be released. This function will therefore 17 * be just temporary, but would probably be kept for a few years. 18 * 19 * @link http://www.hardened-php.net/suhosin/ 20 * @param string $function_name Function to check for 21 * @return bool TRUE if the function exists and is safe to call, 22 * FALSE otherwise. 23 */ 24 function function_usable($function_name) 25 { 26 static $_suhosin_func_blacklist; 27 28 if (function_exists($function_name)) 29 { 30 if ( ! isset($_suhosin_func_blacklist)) 31 { 32 $_suhosin_func_blacklist = extension_loaded('suhosin') 33 ? explode(',', trim(ini_get('suhosin.executor.func.blacklist'))) 34 : array(); 35 } 36 37 return ! in_array($function_name, $_suhosin_func_blacklist, TRUE); 38 } 39 40 return FALSE; 41 }
函数功能类似于function_exist(),不过在外面包装了一层,还需要检查下函数是否在suhosin.executor.func.blacklist中(类似于黑名单?),如果在还是会返回false。