function relative_path(string $target, string $source, string $plus = null, $slash = KE_DS_UNIX) { if ($slash !== KE_DS_UNIX && $slash !== KE_DS_WIN) { $slash = KE_DS_UNIX; } $source = convert_path_slash($source, $slash); $target = convert_path_slash($target, $slash); if (isset($plus)) { $plus = ltrim($plus, KE_PATH_NOISE); } list($source, $phar) = split_phar($source); $relative = $source; if (strlen($source) > 0) { $samePart = compare_path($source, $target, $slash); if (!empty($samePart)) { $samePart = preg_quote($samePart); $quoteSlash = preg_quote($slash); $regex = "#^({$quoteSlash}?{$samePart}{$quoteSlash}?)#i"; $sourceTail = preg_replace($regex, '', $source); $sourceTail = trim($sourceTail, KE_PATH_NOISE); $targetTail = preg_replace($regex, '', $target); $targetTail = trim($targetTail, KE_PATH_NOISE); $targetDepth = 0; if (strlen($targetTail) > 0) { $targetSplit = explode($slash, $targetTail); $targetDepth = count($targetSplit); } $relative = str_repeat($slash . '..', $targetDepth); if (strlen($sourceTail) > 0) { $relative .= $slash . $sourceTail; } } } if ($phar !== false) { $relative = 'phar://' . $relative; $relative .= $slash . $phar; } if (strlen($plus) > 0) { $relative .= $slash . convert_path_slash($plus); } return $relative; }
public final function init() { if ($this->isInit) { return $this; } $env = KE_APP_ENV; // 加载配置 import(["{$this->root}/config/common.php", "{$this->root}/config/{$env}.php"]); if (KE_APP_MODE === KE_WEB) { $this->httpRewrite = (bool) $this->httpRewrite; if (empty($this->httpBase)) { $target = dirname($_SERVER['SCRIPT_NAME']); if ($target === '\\') { $target = '/'; } $this->httpBase = compare_path(KE_REQUEST_PATH, $target, KE_DS_UNIX); } elseif ($this->httpBase !== '/') { $this->httpBase = purge_path($this->httpBase, KE_PATH_DOT_REMOVE ^ KE_PATH_LEFT_TRIM, KE_DS_UNIX); } // 上面的过滤,无论如何,过滤出来的httpBase都为没有首位的/的路径,如:path/dir/dir if (empty($this->httpBase)) { $this->httpBase = '/'; } elseif ($this->httpBase !== '/') { $this->httpBase = '/' . $this->httpBase . '/'; } // 如果不指定重写,则httpBase应该是基于一个php文件为基础的 if (!$this->httpRewrite) { $this->httpBase .= KE_SCRIPT_FILE; } define('KE_HTTP_BASE', $this->httpBase); define('KE_HTTP_REWRITE', (bool) $this->httpRewrite); } ///////////////////////////////////////////////////////////////////////////// // p2:填充当前的APP实例的数据 ///////////////////////////////////////////////////////////////////////////// // 初始化项目的名称 => 不应为空,也必须是一个字符串 if (empty($this->name) || !is_string($this->name)) { $this->name = KE_APP_DIR; } // 一个App的完整摘要 $summary = sprintf('%s(%s,%s,%s)', $this->name, KE_APP_ENV, KE_REQUEST_HOST, $this->root); // 项目的hash,基于完整摘要生成,而非基于用户设置的项目名称 // hash,主要用于服务器缓存识别不同的项目时使用 // 比如memcached,key为user.10,而这个项目的存储则应该是:$flag.user.10,来避免项目和项目之间的数据混串 $hash = hash('crc32b', $summary); // 真正用于显示的项目名称,包含项目名称、环境、hash $this->name = sprintf('%s(%s:%s)', $this->name, KE_APP_ENV, $hash); // 项目的基本加密混淆码 => 不应为空,也必须是一个字符串,且必须不小于32长度 if (empty($this->salt) || !is_string($this->salt) || strlen($this->salt) < 32) { $salt = $summary; } else { $salt = $this->salt; } define('KE_APP_NAME', $this->name); define('KE_APP_HASH', $hash); define('KE_APP_SALT', hash('sha512', $salt, true)); // 敏感数据还是清空为妙 $this->salt = null; // http验证字段,如果没指定,就只好使用一个统一的了 if (empty($this->httpSecurityField) || !is_string($this->httpSecurityField)) { $this->httpSecurityField = 'ke_http'; } if (empty($this->httpSecuritySessionField) || !is_string($this->httpSecuritySessionField)) { $this->httpSecuritySessionField = 'ke_security_reference'; } // http验证字段的加密混淆码 if (empty($this->httpSecuritySalt) || !is_string($this->httpSecuritySalt)) { $this->httpSecuritySalt = "{$this->name}:{$this->httpSecurityField}"; } $this->httpSecuritySalt = $this->hash($this->httpSecuritySalt); define('KE_HTTP_SECURITY_FIELD', $this->httpSecurityField); define('KE_HTTP_SECURITY_SALT', $this->httpSecuritySalt); define('KE_HTTP_SECURITY_SESS_FIELD', $this->httpSecuritySessionField); // 敏感数据还是清空为妙 $this->httpSecuritySalt = null; // 检查httpCharset if (empty($this->encoding) || false === @mb_encoding_aliases($this->encoding)) { $this->encoding = 'UTF-8'; } if (!empty($this->encodingOrder)) { if (is_string($this->encodingOrder)) { $this->encodingOrder = explode(',', $this->encodingOrder); } if (is_array($this->encodingOrder)) { $list = ['ASCII']; foreach ($this->encodingOrder as $encoding) { $encoding = strtoupper(trim($encoding)); if (empty($encoding) || $encoding === 'ASCII' || $encoding === $this->encoding) { continue; } $list[] = $encoding; } $list[] = $this->encoding; mb_detect_order($list); } } // 时区 if (empty($this->timezone) || false === @date_default_timezone_set($this->timezone)) { $this->timezone = 'Asia/Shanghai'; date_default_timezone_set($this->timezone); } define('KE_APP_TIMEZONE', $this->timezone); define('KE_APP_ENCODING', $this->encoding); // 系统的配置 ini_set('default_charset', KE_APP_ENCODING); ini_set('default_mimetype', 'text/html'); mb_internal_encoding(KE_APP_ENCODING); mb_http_output(KE_APP_ENCODING); $this->isInit = true; call_user_func([$this, 'on' . KE_APP_ENV]); register_shutdown_function(function () { $this->onExiting(); }); return $this; }
public function filterFile(string $file = null) { $file = DocMen::convertUnixPath($file); if (!isset($this->_files[$file])) { $isFile = is_file($file) && is_readable($file); $dir = $this->source; $base = $dir . '/'; if (!$isFile) { // 空文件,将视作为php internal if (empty($file)) { $dir = $this->addDir(''); $path = ''; $priority = 0; } else { return false; } } else { if (strpos($file, $base) === 0) { $path = substr($file, strlen($base)); } else { $dir = compare_path($this->source, $file); if (empty($dir)) { $dir = $this->addDir(dirname($file)); $path = basename($file); } else { $dir = $this->addDir($dir); $path = substr($file, strlen($dir . '/')); } } } $key = $path; $id = $this->getDirIndex($dir); $data = ['isFile' => is_file($file), 'dir' => $id, 'path' => $path]; // 写入基础数据 $this->_files[$file] = $this->_files[$path] = $key; $this->files[$key] = $data; // 写入排序数据 $this->_filesSort['priority'][$path] = $this->getFilePriority($path); $this->_filesSort['external'][$path] = $id; $this->_filesSort['depth'][$path] = count(explode('/', $path)); $this->_filesSort['name'][$path] = $path; return $data; } $index = $this->_files[$file]; return $this->files[$index]; }