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 (!defined('DISCUZ_LOG_FUNCTION') && !@include(DISCUZ_ROOT . './source/function/function_log.php')) { exit('function_log.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]); } } if (!defined('APPTYPEID')) { define('APPTYPEID', 0); } if (!defined('DISCUZ_APP')) { define('DISCUZ_APP', ''); } if (!defined('CURSCRIPT')) { define('CURSCRIPT', DISCUZ_APP); } 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' => '', 'authkey' => '', 'timenow' => [], 'widthauto' => 0, 'disabledwidthauto' => 0, 'PHP_SELF' => '', 'siteurl' => '', 'siteroot' => '', 'siteport' => '', 'pluginrunlist' => !defined('PLUGINRUNLIST') ? [] : explode(',', PLUGINRUNLIST), 'config' => & $this->config, 'setting' => [], 'member' => [], 'group' => [], 'cookie' => [], 'style' => [], 'cache' => [], 'session' => [], 'lang' => [], 'fid' => 0, 'tid' => 0, 'forum' => [], 'thread' => [], 'rssauth' => '', 'home' => [], 'space' => [], 'block' => [], 'article' => [], 'action' => [ 'action' => APPTYPEID, 'fid' => 0, 'tid' => 0, ], 'mobile' => '', 'notice_structure' => [ 'mypost' => ['post', 'rate', 'pcomment', 'activity', 'reward', 'goods', 'at'], 'interactive' => ['poke', 'friend', 'wall', 'comment', 'click', 'sharenotice'], 'system' => ['system', 'credit', 'group', 'verify', 'magic', 'task', 'show', 'group', 'pusearticle', 'mod_member', 'blog', 'article'], 'manage' => ['mod_member', 'report', 'pmreport'], 'app' => [], ], 'mobiletpl' => ['1' => 'touch', '2' => 'touch', '3' => 'touch', 'yes' => 'touch'], ]; $_G['PHP_SELF'] = dhtmlspecialchars($this->_get_script_url()); $_G['basescript'] = CURSCRIPT; $_G['basefilename'] = basename($_G['PHP_SELF']); $sitepath = substr($_G['PHP_SELF'], 0, strrpos($_G['PHP_SELF'], '/')); if (defined('IN_API')) { $sitepath = preg_replace('/\/api\/?.*?$/i', '', $sitepath); } elseif (defined('IN_ARCHIVER')) { $sitepath = preg_replace('/\/archiver/i', '', $sitepath); } if (defined('IN_NEWMOBILE')) { $sitepath = preg_replace('/\/m/i', '', $sitepath); } $_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']; if (defined('SUB_DIR')) { $_G['siteurl'] = str_replace(SUB_DIR, '/', $_G['siteurl']); $_G['siteroot'] = str_replace(SUB_DIR, '/', $_G['siteroot']); } $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'])) { system_error('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']); } } }