1, '_GET' => 1, '_POST' => 1, '_REQUEST' => 1, '_COOKIE' => 1, '_SERVER' => 1, '_ENV' => 1, '_FILES' => 1, ]; static function &instance() { static $object; if (empty($object)) { $object = new self(); } return $object; } public function __construct() { $this->_init_env(); $this->_init_input(); $this->_init_output(); } public function init() { if (!$this->initated) { $this->_init_db(); } $this->initated = true; } private function _init_env() { error_reporting(E_ERROR); define('ICONV_ENABLE', function_exists('iconv')); define('MB_ENABLE', function_exists('mb_convert_encoding')); define('EXT_OBGZIP', function_exists('ob_gzhandler')); define('TIMESTAMP', time()); if (!defined('DISCUZ_CORE_FUNCTION') && !@include(DISCUZ_ROOT . './source/function/function_core.php')) { exit('function_core.php is missing'); } if (function_exists('ini_get')) { $memorylimit = @ini_get('memory_limit'); if ($memorylimit && return_bytes($memorylimit) < 33554432 && function_exists('ini_set')) { ini_set('memory_limit', '128m'); } } define('IS_ROBOT', checkrobot()); foreach ($GLOBALS as $key => $value) { if (!isset($this->superglobal[$key])) { $GLOBALS[$key] = null; unset($GLOBALS[$key]); } } global $_G; $_G = [ 'uid' => 0, 'username' => '', 'adminid' => 0, 'groupid' => 1, 'sid' => '', 'formhash' => '', 'connectguest' => 0, 'timestamp' => TIMESTAMP, 'starttime' => microtime(true), 'clientip' => $this->_get_client_ip(), 'remoteport' => $_SERVER['REMOTE_PORT'], 'referer' => '', 'charset' => '', 'gzipcompress' => '', ]; $_G['PHP_SELF'] = dhtmlspecialchars($this->_get_script_url()); $_G['basefilename'] = basename($_G['PHP_SELF']); $_G['isHTTPS'] = !empty($_G['config']['output']['forcehttps']) || $this->_is_https(); $_G['scheme'] = 'http' . ($_G['isHTTPS'] ? 's' : ''); $_G['siteurl'] = dhtmlspecialchars($_G['scheme'] . '://' . $_SERVER['HTTP_HOST'] . $sitepath . '/'); $url = parse_url($_G['siteurl']); $_G['siteroot'] = $url['path'] ?? ''; $_G['siteport'] = empty($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == '80' || $_SERVER['SERVER_PORT'] == '443' ? '' : ':' . $_SERVER['SERVER_PORT']; $this->var = &$_G; } private function _get_script_url() { if (!isset($this->var['PHP_SELF'])) { $scriptName = basename($_SERVER['SCRIPT_FILENAME']); if (basename($_SERVER['SCRIPT_NAME']) === $scriptName) { $this->var['PHP_SELF'] = $_SERVER['SCRIPT_NAME']; } else if (basename($_SERVER['PHP_SELF']) === $scriptName) { $this->var['PHP_SELF'] = $_SERVER['PHP_SELF']; } else if (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $scriptName) { $this->var['PHP_SELF'] = $_SERVER['ORIG_SCRIPT_NAME']; } else if (($pos = strpos($_SERVER['PHP_SELF'], '/' . $scriptName)) !== false) { $this->var['PHP_SELF'] = substr($_SERVER['SCRIPT_NAME'], 0, $pos) . '/' . $scriptName; } else if (isset($_SERVER['DOCUMENT_ROOT']) && str_starts_with($_SERVER['SCRIPT_FILENAME'], $_SERVER['DOCUMENT_ROOT'])) { $this->var['PHP_SELF'] = str_replace('\\', '/', str_replace($_SERVER['DOCUMENT_ROOT'], '', $_SERVER['SCRIPT_FILENAME'])); $this->var['PHP_SELF'][0] != '/' && $this->var['PHP_SELF'] = '/' . $this->var['PHP_SELF']; } else { system_error('request_tainting'); } } return $this->var['PHP_SELF']; } private function _init_input() { if (isset($_GET['GLOBALS']) || isset($_POST['GLOBALS']) || isset($_COOKIE['GLOBALS']) || isset($_FILES['GLOBALS'])) { exit('request tainting'); } $prelength = strlen($this->config['cookie']['cookiepre']); foreach ($_COOKIE as $key => $val) { if (substr($key, 0, $prelength) == $this->config['cookie']['cookiepre']) { $this->var['cookie'][substr($key, $prelength)] = $val; } } if ($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_POST)) { foreach ($_POST as $k => $v) { $_GET[$k] = $v; } } } private function _init_output() { if (!empty($_SERVER['HTTP_ACCEPT_ENCODING']) && !str_contains($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) { $this->config['output']['gzip'] = false; } $allowgzip = $this->config['output']['gzip'] && empty($this->var['inajax']) && $this->var['mod'] != 'attachment' && EXT_OBGZIP; setglobal('gzipcompress', $allowgzip); if (!ob_start($allowgzip ? 'ob_gzhandler' : null)) { ob_start(); } setglobal('charset', $this->config['output']['charset']); define('CHARSET', $this->config['output']['charset']); if ($this->config['output']['forceheader']) { @header('Content-Type: text/html; charset=' . CHARSET); } if ($this->var['isHTTPS'] && isset($this->config['output']['upgradeinsecure']) && $this->config['output']['upgradeinsecure']) { @header('Content-Security-Policy: upgrade-insecure-requests'); } } public function reject_robot() { if (IS_ROBOT) { exit(header('HTTP/1.1 403 Forbidden')); } } private function _is_https() { // PHP 标准服务器变量 if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') { return true; } // X-Forwarded-Proto 事实标准头部, 用于反代透传 HTTPS 状态 if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') { return true; } // 阿里云全站加速私有 HTTPS 状态头部 // Git 意见反馈 https://gitee.com/Discuz/DiscuzX/issues/I3W5GP if (isset($_SERVER['HTTP_X_CLIENT_SCHEME']) && strtolower($_SERVER['HTTP_X_CLIENT_SCHEME']) == 'https') { return true; } // 西部数码建站助手私有 HTTPS 状态头部 // 官网意见反馈 https://discuz.dismall.com/thread-3849819-1-1.html if (isset($_SERVER['HTTP_FROM_HTTPS']) && strtolower($_SERVER['HTTP_FROM_HTTPS']) != 'off') { return true; } // 服务器端口号兜底判断 if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) { return true; } return false; } private function _get_client_ip() { $ip = $_SERVER['REMOTE_ADDR']; if (!array_key_exists('security', $this->config) || !$this->config['security']['onlyremoteaddr']) { if (array_key_exists('ipgetter', $this->config) && !empty($this->config['ipgetter']['setting'])) { $s = empty($this->config['ipgetter'][$this->config['ipgetter']['setting']]) ? [] : $this->config['ipgetter'][$this->config['ipgetter']['setting']]; $c = 'ip_getter_' . $this->config['ipgetter']['setting']; $r = $c::get($s); $ip = ip::validate_ip($r) ? $r : $ip; } elseif (isset($_SERVER['HTTP_CLIENT_IP']) && ip::validate_ip($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') > 0) { $exp = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $ip = ip::validate_ip(trim($exp[0])) ? $exp[0] : $ip; } else { $ip = ip::validate_ip($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $ip; } } } return $ip; } private function _init_db() { if ($this->init_db && $this->config) { if ($this->config['db']['driver'] == 'pdo' && class_exists('PDO')) { $driver = 'db_driver_pdo'; if (getglobal('config/db/slave')) { $driver = 'db_driver_pdo_slave'; } $this->var['db_driver'] = 'pdo'; } else { $driver = 'db_driver_mysqli'; if (getglobal('config/db/slave')) { $driver = 'db_driver_mysqli_slave'; } $this->var['db_driver'] = 'mysqli'; } $this->var['mysql_driver'] = $driver; DB::init($driver, $this->config['db']); } } }