You've already forked qlg.tsgz.moe
addons
app_download_files
extend
hyhproject
mobile
oss
static
thinkphp
lang
library
think
cache
config
controller
db
debug
exception
log
model
paginator
process
response
session
template
view
App.php
Build.php
Cache.php
Collection.php
Config.php
Console.php
Controller.php
Cookie.php
Db.php
Debug.php
Env.php
Error.php
Exception.php
File.php
Hook.php
Lang.php
Loader.php
Log.php
Model.php
Paginator.php
Process.php
Request.php
Response.php
Route.php
Session.php
Template.php
Url.php
Validate.php
View.php
traits
tpl
.htaccess
LICENSE.txt
README.md
base.php
convention.php
helper.php
logo.png
start.php
upload
vendor
wxtmp
.gitignore
.htaccess
.user.ini
404.html
H5B854518.wgt
admin.php
app-release.apk
app_download.html
cash.lock
demo.php
get_startup.php
get_version.php
get_version_new.php
index.html
index.php
qlg.tar.gz
reg.lock
robots.txt
571 lines
19 KiB
PHP
Executable File
571 lines
19 KiB
PHP
Executable File
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
|
// +----------------------------------------------------------------------
|
|
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
|
|
// +----------------------------------------------------------------------
|
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
|
// +----------------------------------------------------------------------
|
|
// | Author: liu21st <liu21st@gmail.com>
|
|
// +----------------------------------------------------------------------
|
|
|
|
namespace think;
|
|
|
|
use think\exception\ClassNotFoundException;
|
|
|
|
class Loader
|
|
{
|
|
protected static $instance = [];
|
|
// 类名映射
|
|
protected static $map = [];
|
|
|
|
// 命名空间别名
|
|
protected static $namespaceAlias = [];
|
|
|
|
// PSR-4
|
|
private static $prefixLengthsPsr4 = [];
|
|
private static $prefixDirsPsr4 = [];
|
|
private static $fallbackDirsPsr4 = [];
|
|
|
|
// PSR-0
|
|
private static $prefixesPsr0 = [];
|
|
private static $fallbackDirsPsr0 = [];
|
|
|
|
// 自动加载的文件
|
|
private static $autoloadFiles = [];
|
|
|
|
// 自动加载
|
|
public static function autoload($class)
|
|
{
|
|
// 检测命名空间别名
|
|
if (!empty(self::$namespaceAlias)) {
|
|
$namespace = dirname($class);
|
|
if (isset(self::$namespaceAlias[$namespace])) {
|
|
$original = self::$namespaceAlias[$namespace] . '\\' . basename($class);
|
|
if (class_exists($original)) {
|
|
return class_alias($original, $class, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($file = self::findFile($class)) {
|
|
|
|
// Win环境严格区分大小写
|
|
if (IS_WIN && pathinfo($file, PATHINFO_FILENAME) != pathinfo(realpath($file), PATHINFO_FILENAME)) {
|
|
return false;
|
|
}
|
|
|
|
__include_file($file);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 查找文件
|
|
* @param $class
|
|
* @return bool
|
|
*/
|
|
private static function findFile($class)
|
|
{
|
|
if (!empty(self::$map[$class])) {
|
|
// 类库映射
|
|
return self::$map[$class];
|
|
}
|
|
|
|
// 查找 PSR-4
|
|
$logicalPathPsr4 = strtr($class, '\\', DS) . EXT;
|
|
|
|
$first = $class[0];
|
|
if (isset(self::$prefixLengthsPsr4[$first])) {
|
|
foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) {
|
|
if (0 === strpos($class, $prefix)) {
|
|
foreach (self::$prefixDirsPsr4[$prefix] as $dir) {
|
|
if (is_file($file = $dir . DS . substr($logicalPathPsr4, $length))) {
|
|
return $file;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 查找 PSR-4 fallback dirs
|
|
foreach (self::$fallbackDirsPsr4 as $dir) {
|
|
if (is_file($file = $dir . DS . $logicalPathPsr4)) {
|
|
return $file;
|
|
}
|
|
}
|
|
|
|
// 查找 PSR-0
|
|
if (false !== $pos = strrpos($class, '\\')) {
|
|
// namespaced class name
|
|
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
|
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DS);
|
|
} else {
|
|
// PEAR-like class name
|
|
$logicalPathPsr0 = strtr($class, '_', DS) . EXT;
|
|
}
|
|
|
|
if (isset(self::$prefixesPsr0[$first])) {
|
|
foreach (self::$prefixesPsr0[$first] as $prefix => $dirs) {
|
|
if (0 === strpos($class, $prefix)) {
|
|
foreach ($dirs as $dir) {
|
|
if (is_file($file = $dir . DS . $logicalPathPsr0)) {
|
|
return $file;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 查找 PSR-0 fallback dirs
|
|
foreach (self::$fallbackDirsPsr0 as $dir) {
|
|
if (is_file($file = $dir . DS . $logicalPathPsr0)) {
|
|
return $file;
|
|
}
|
|
}
|
|
|
|
return self::$map[$class] = false;
|
|
}
|
|
|
|
// 注册classmap
|
|
public static function addClassMap($class, $map = '')
|
|
{
|
|
if (is_array($class)) {
|
|
self::$map = array_merge(self::$map, $class);
|
|
} else {
|
|
self::$map[$class] = $map;
|
|
}
|
|
}
|
|
|
|
// 注册命名空间
|
|
public static function addNamespace($namespace, $path = '')
|
|
{
|
|
if (is_array($namespace)) {
|
|
foreach ($namespace as $prefix => $paths) {
|
|
self::addPsr4($prefix . '\\', rtrim($paths, DS), true);
|
|
}
|
|
} else {
|
|
self::addPsr4($namespace . '\\', rtrim($path, DS), true);
|
|
}
|
|
}
|
|
|
|
// 添加Ps0空间
|
|
private static function addPsr0($prefix, $paths, $prepend = false)
|
|
{
|
|
if (!$prefix) {
|
|
if ($prepend) {
|
|
self::$fallbackDirsPsr0 = array_merge(
|
|
(array) $paths,
|
|
self::$fallbackDirsPsr0
|
|
);
|
|
} else {
|
|
self::$fallbackDirsPsr0 = array_merge(
|
|
self::$fallbackDirsPsr0,
|
|
(array) $paths
|
|
);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
$first = $prefix[0];
|
|
if (!isset(self::$prefixesPsr0[$first][$prefix])) {
|
|
self::$prefixesPsr0[$first][$prefix] = (array) $paths;
|
|
|
|
return;
|
|
}
|
|
if ($prepend) {
|
|
self::$prefixesPsr0[$first][$prefix] = array_merge(
|
|
(array) $paths,
|
|
self::$prefixesPsr0[$first][$prefix]
|
|
);
|
|
} else {
|
|
self::$prefixesPsr0[$first][$prefix] = array_merge(
|
|
self::$prefixesPsr0[$first][$prefix],
|
|
(array) $paths
|
|
);
|
|
}
|
|
}
|
|
|
|
// 添加Psr4空间
|
|
private static function addPsr4($prefix, $paths, $prepend = false)
|
|
{
|
|
if (!$prefix) {
|
|
// Register directories for the root namespace.
|
|
if ($prepend) {
|
|
self::$fallbackDirsPsr4 = array_merge(
|
|
(array) $paths,
|
|
self::$fallbackDirsPsr4
|
|
);
|
|
} else {
|
|
self::$fallbackDirsPsr4 = array_merge(
|
|
self::$fallbackDirsPsr4,
|
|
(array) $paths
|
|
);
|
|
}
|
|
} elseif (!isset(self::$prefixDirsPsr4[$prefix])) {
|
|
// Register directories for a new namespace.
|
|
$length = strlen($prefix);
|
|
if ('\\' !== $prefix[$length - 1]) {
|
|
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
|
}
|
|
self::$prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
|
self::$prefixDirsPsr4[$prefix] = (array) $paths;
|
|
} elseif ($prepend) {
|
|
// Prepend directories for an already registered namespace.
|
|
self::$prefixDirsPsr4[$prefix] = array_merge(
|
|
(array) $paths,
|
|
self::$prefixDirsPsr4[$prefix]
|
|
);
|
|
} else {
|
|
// Append directories for an already registered namespace.
|
|
self::$prefixDirsPsr4[$prefix] = array_merge(
|
|
self::$prefixDirsPsr4[$prefix],
|
|
(array) $paths
|
|
);
|
|
}
|
|
}
|
|
|
|
// 注册命名空间别名
|
|
public static function addNamespaceAlias($namespace, $original = '')
|
|
{
|
|
if (is_array($namespace)) {
|
|
self::$namespaceAlias = array_merge(self::$namespaceAlias, $namespace);
|
|
} else {
|
|
self::$namespaceAlias[$namespace] = $original;
|
|
}
|
|
}
|
|
|
|
// 注册自动加载机制
|
|
public static function register($autoload = '')
|
|
{
|
|
// 注册系统自动加载
|
|
spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);
|
|
// 注册命名空间定义
|
|
self::addNamespace([
|
|
'think' => LIB_PATH . 'think' . DS,
|
|
'behavior' => LIB_PATH . 'behavior' . DS,
|
|
'traits' => LIB_PATH . 'traits' . DS,
|
|
]);
|
|
// 加载类库映射文件
|
|
if (is_file(RUNTIME_PATH . 'classmap' . EXT)) {
|
|
self::addClassMap(__include_file(RUNTIME_PATH . 'classmap' . EXT));
|
|
}
|
|
|
|
// Composer自动加载支持
|
|
if (is_dir(VENDOR_PATH . 'composer')) {
|
|
self::registerComposerLoader();
|
|
}
|
|
|
|
// 自动加载extend目录
|
|
self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS);
|
|
}
|
|
|
|
// 注册composer自动加载
|
|
private static function registerComposerLoader()
|
|
{
|
|
if (is_file(VENDOR_PATH . 'composer/autoload_namespaces.php')) {
|
|
$map = require VENDOR_PATH . 'composer/autoload_namespaces.php';
|
|
foreach ($map as $namespace => $path) {
|
|
self::addPsr0($namespace, $path);
|
|
}
|
|
}
|
|
|
|
if (is_file(VENDOR_PATH . 'composer/autoload_psr4.php')) {
|
|
$map = require VENDOR_PATH . 'composer/autoload_psr4.php';
|
|
foreach ($map as $namespace => $path) {
|
|
self::addPsr4($namespace, $path);
|
|
}
|
|
}
|
|
|
|
if (is_file(VENDOR_PATH . 'composer/autoload_classmap.php')) {
|
|
$classMap = require VENDOR_PATH . 'composer/autoload_classmap.php';
|
|
if ($classMap) {
|
|
self::addClassMap($classMap);
|
|
}
|
|
}
|
|
|
|
if (is_file(VENDOR_PATH . 'composer/autoload_files.php')) {
|
|
$includeFiles = require VENDOR_PATH . 'composer/autoload_files.php';
|
|
foreach ($includeFiles as $fileIdentifier => $file) {
|
|
if (empty(self::$autoloadFiles[$fileIdentifier])) {
|
|
__require_file($file);
|
|
self::$autoloadFiles[$fileIdentifier] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 导入所需的类库 同java的Import 本函数有缓存功能
|
|
* @param string $class 类库命名空间字符串
|
|
* @param string $baseUrl 起始路径
|
|
* @param string $ext 导入的文件扩展名
|
|
* @return boolean
|
|
*/
|
|
public static function import($class, $baseUrl = '', $ext = EXT)
|
|
{
|
|
static $_file = [];
|
|
$key = $class . $baseUrl;
|
|
$class = str_replace(['.', '#'], [DS, '.'], $class);
|
|
if (isset($_file[$key])) {
|
|
return true;
|
|
}
|
|
|
|
if (empty($baseUrl)) {
|
|
list($name, $class) = explode(DS, $class, 2);
|
|
|
|
if (isset(self::$prefixDirsPsr4[$name . '\\'])) {
|
|
// 注册的命名空间
|
|
$baseUrl = self::$prefixDirsPsr4[$name . '\\'];
|
|
} elseif ('@' == $name) {
|
|
//加载当前模块应用类库
|
|
$baseUrl = App::$modulePath;
|
|
} elseif (is_dir(EXTEND_PATH . $name)) {
|
|
$baseUrl = EXTEND_PATH . $name . DS;
|
|
} else {
|
|
// 加载其它模块的类库
|
|
$baseUrl = APP_PATH . $name . DS;
|
|
}
|
|
} elseif (substr($baseUrl, -1) != DS) {
|
|
$baseUrl .= DS;
|
|
}
|
|
// 如果类存在 则导入类库文件
|
|
if (is_array($baseUrl)) {
|
|
foreach ($baseUrl as $path) {
|
|
$filename = $path . DS . $class . $ext;
|
|
if (is_file($filename)) {
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
$filename = $baseUrl . $class . $ext;
|
|
}
|
|
|
|
if (!empty($filename) && is_file($filename)) {
|
|
// 开启调试模式Win环境严格区分大小写
|
|
if (IS_WIN && pathinfo($filename, PATHINFO_FILENAME) != pathinfo(realpath($filename), PATHINFO_FILENAME)) {
|
|
return false;
|
|
}
|
|
__include_file($filename);
|
|
$_file[$key] = true;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* 实例化(分层)模型
|
|
* @param string $name Model名称
|
|
* @param string $layer 业务层名称
|
|
* @param bool $appendSuffix 是否添加类名后缀
|
|
* @param string $common 公共模块名
|
|
* @return object
|
|
* @throws ClassNotFoundException
|
|
*/
|
|
public static function model($name = '', $layer = 'model', $appendSuffix = false, $common = 'common')
|
|
{
|
|
$guid = $name . $layer;
|
|
if (isset(self::$instance[$guid])) {
|
|
return self::$instance[$guid];
|
|
}
|
|
list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix);
|
|
if (class_exists($class)) {
|
|
$model = new $class();
|
|
} else {
|
|
$class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class);
|
|
if (class_exists($class)) {
|
|
$model = new $class();
|
|
} else {
|
|
throw new ClassNotFoundException('class not exists:' . $class, $class);
|
|
}
|
|
}
|
|
self::$instance[$guid] = $model;
|
|
return $model;
|
|
}
|
|
|
|
/**
|
|
* 实例化(分层)控制器 格式:[模块名/]控制器名
|
|
* @param string $name 资源地址
|
|
* @param string $layer 控制层名称
|
|
* @param bool $appendSuffix 是否添加类名后缀
|
|
* @param string $empty 空控制器名称
|
|
* @return object
|
|
* @throws ClassNotFoundException
|
|
*/
|
|
public static function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '')
|
|
{
|
|
list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix);
|
|
if (class_exists($class)) {
|
|
return App::invokeClass($class);
|
|
} elseif ($empty && class_exists($emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix))) {
|
|
return new $emptyClass(Request::instance());
|
|
} else {
|
|
throw new ClassNotFoundException('class not exists:' . $class, $class);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 实例化验证类 格式:[模块名/]验证器名
|
|
* modify by GZShangTao
|
|
* @param string $name 资源地址
|
|
* @param string $layer 验证层名称
|
|
* @param bool $appendSuffix 是否添加类名后缀
|
|
* @param string $common 公共模块名
|
|
* @return object|false
|
|
* @throws ClassNotFoundException
|
|
*/
|
|
public static function validate($name = '', $layer = 'validate', $appendSuffix = false, $common = 'common',$otherNamespace = '')
|
|
{
|
|
$name = $name ?: Config::get('default_validate');
|
|
if (empty($name)) {
|
|
return new Validate;
|
|
}
|
|
$guid = $name . $layer;
|
|
if (isset(self::$instance[$guid])) {
|
|
return self::$instance[$guid];
|
|
}
|
|
list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix,$otherNamespace);
|
|
if (class_exists($class)) {
|
|
$validate = new $class;
|
|
} else {
|
|
$class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class);
|
|
if (class_exists($class)) {
|
|
$validate = new $class;
|
|
} else {
|
|
throw new ClassNotFoundException('class not exists:' . $class, $class);
|
|
}
|
|
}
|
|
self::$instance[$guid] = $validate;
|
|
return $validate;
|
|
}
|
|
|
|
/**
|
|
* 解析模块和类名
|
|
* modify by GZShangTao
|
|
* @param string $name 资源地址
|
|
* @param string $layer 验证层名称
|
|
* @param bool $appendSuffix 是否添加类名后缀
|
|
* @return array
|
|
*/
|
|
protected static function getModuleAndClass($name, $layer, $appendSuffix,$otherNamespace = '')
|
|
{
|
|
if (false !== strpos($name, '\\')) {
|
|
$module = Request::instance()->module();
|
|
$class = $name;
|
|
} else {
|
|
if (strpos($name, '/')) {
|
|
list($module, $name) = explode('/', $name, 2);
|
|
} else {
|
|
$module = Request::instance()->module();
|
|
}
|
|
$class = self::parseClass($module, $layer, $name, $appendSuffix,$otherNamespace);
|
|
}
|
|
return [$module, $class];
|
|
}
|
|
|
|
/**
|
|
* 数据库初始化 并取得数据库类实例
|
|
* @param mixed $config 数据库配置
|
|
* @param bool|string $name 连接标识 true 强制重新连接
|
|
* @return \think\db\Connection
|
|
*/
|
|
public static function db($config = [], $name = false)
|
|
{
|
|
return Db::connect($config, $name);
|
|
}
|
|
|
|
/**
|
|
* 远程调用模块的操作方法 参数格式 [模块/控制器/]操作
|
|
* @param string $url 调用地址
|
|
* @param string|array $vars 调用参数 支持字符串和数组
|
|
* @param string $layer 要调用的控制层名称
|
|
* @param bool $appendSuffix 是否添加类名后缀
|
|
* @return mixed
|
|
*/
|
|
public static function action($url, $vars = [], $layer = 'controller', $appendSuffix = false)
|
|
{
|
|
$info = pathinfo($url);
|
|
$action = $info['basename'];
|
|
$module = '.' != $info['dirname'] ? $info['dirname'] : Request::instance()->controller();
|
|
$class = self::controller($module, $layer, $appendSuffix);
|
|
if ($class) {
|
|
if (is_scalar($vars)) {
|
|
if (strpos($vars, '=')) {
|
|
parse_str($vars, $vars);
|
|
} else {
|
|
$vars = [$vars];
|
|
}
|
|
}
|
|
return App::invokeMethod([$class, $action . Config::get('action_suffix')], $vars);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 字符串命名风格转换
|
|
* type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
|
|
* @param string $name 字符串
|
|
* @param integer $type 转换类型
|
|
* @param bool $ucfirst 首字母是否大写(驼峰规则)
|
|
* @return string
|
|
*/
|
|
public static function parseName($name, $type = 0, $ucfirst = true)
|
|
{
|
|
if ($type) {
|
|
$name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {
|
|
return strtoupper($match[1]);
|
|
}, $name);
|
|
return $ucfirst ? ucfirst($name) : lcfirst($name);
|
|
} else {
|
|
return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 解析应用类的类名
|
|
* modify by GZShangTao
|
|
* @param string $module 模块名
|
|
* @param string $layer 层名 controller model ...
|
|
* @param string $name 类名
|
|
* @param bool $appendSuffix
|
|
* @return string
|
|
*/
|
|
public static function parseClass($module, $layer, $name, $appendSuffix = false,$otherNamespace = '')
|
|
{
|
|
$name = str_replace(['/', '.'], '\\', $name);
|
|
$array = explode('\\', $name);
|
|
$class = self::parseName(array_pop($array), 1) . (App::$suffix || $appendSuffix ? ucfirst($layer) : '');
|
|
$path = $array ? implode('\\', $array) . '\\' : '';
|
|
if($otherNamespace!=''){
|
|
return $otherNamespace . '\\' . ($module ? $module . '\\' : '') . $layer . '\\' . $path . $class;
|
|
}else{
|
|
return App::$namespace . '\\' . ($module ? $module . '\\' : '') . $layer . '\\' . $path . $class;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 初始化类的实例
|
|
* @return void
|
|
*/
|
|
public static function clearInstance()
|
|
{
|
|
self::$instance = [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 作用范围隔离
|
|
*
|
|
* @param $file
|
|
* @return mixed
|
|
*/
|
|
function __include_file($file)
|
|
{
|
|
return include $file;
|
|
}
|
|
|
|
function __require_file($file)
|
|
{
|
|
return require $file;
|
|
}
|