| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610 |
- <?php
- // +----------------------------------------------------------------------
- // | ThinkPHP [ WE CAN DO IT JUST THINK ]
- // +----------------------------------------------------------------------
- // | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
- // +----------------------------------------------------------------------
- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
- // +----------------------------------------------------------------------
- // | Author: liu21st <liu21st@gmail.com>
- // +----------------------------------------------------------------------
- declare (strict_types = 1);
- namespace think;
- use think\event\AppInit;
- use think\helper\Str;
- use think\initializer\BootService;
- use think\initializer\Error;
- use think\initializer\RegisterService;
- /**
- * App 基础类
- * @property Route $route
- * @property Config $config
- * @property Cache $cache
- * @property Request $request
- * @property Http $http
- * @property Console $console
- * @property Env $env
- * @property Event $event
- * @property Middleware $middleware
- * @property Log $log
- * @property Lang $lang
- * @property Db $db
- * @property Cookie $cookie
- * @property Session $session
- * @property Validate $validate
- * @property Filesystem $filesystem
- */
- class App extends Container
- {
- const VERSION = '6.0.0';
- /**
- * 应用调试模式
- * @var bool
- */
- protected $appDebug = false;
- /**
- * 应用开始时间
- * @var float
- */
- protected $beginTime;
- /**
- * 应用内存初始占用
- * @var integer
- */
- protected $beginMem;
- /**
- * 当前应用类库命名空间
- * @var string
- */
- protected $namespace = 'app';
- /**
- * 应用根目录
- * @var string
- */
- protected $rootPath = '';
- /**
- * 框架目录
- * @var string
- */
- protected $thinkPath = '';
- /**
- * 应用目录
- * @var string
- */
- protected $appPath = '';
- /**
- * Runtime目录
- * @var string
- */
- protected $runtimePath = '';
- /**
- * 路由定义目录
- * @var string
- */
- protected $routePath = '';
- /**
- * 配置后缀
- * @var string
- */
- protected $configExt = '.php';
- /**
- * 应用初始化器
- * @var array
- */
- protected $initializers = [
- Error::class,
- RegisterService::class,
- BootService::class,
- ];
- /**
- * 注册的系统服务
- * @var array
- */
- protected $services = [];
- /**
- * 初始化
- * @var bool
- */
- protected $initialized = false;
- /**
- * 容器绑定标识
- * @var array
- */
- protected $bind = [
- 'app' => App::class,
- 'cache' => Cache::class,
- 'config' => Config::class,
- 'console' => Console::class,
- 'cookie' => Cookie::class,
- 'db' => Db::class,
- 'env' => Env::class,
- 'event' => Event::class,
- 'http' => Http::class,
- 'lang' => Lang::class,
- 'log' => Log::class,
- 'middleware' => Middleware::class,
- 'request' => Request::class,
- 'response' => Response::class,
- 'route' => Route::class,
- 'session' => Session::class,
- 'validate' => Validate::class,
- 'view' => View::class,
- 'filesystem' => Filesystem::class,
- 'think\DbManager' => Db::class,
- 'think\LogManager' => Log::class,
- 'think\CacheManager' => Cache::class,
- // 接口依赖注入
- 'Psr\Log\LoggerInterface' => Log::class,
- ];
- /**
- * 架构方法
- * @access public
- * @param string $rootPath 应用根目录
- */
- public function __construct(string $rootPath = '')
- {
- $this->thinkPath = dirname(__DIR__) . DIRECTORY_SEPARATOR;
- $this->rootPath = $rootPath ? rtrim($rootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $this->getDefaultRootPath();
- $this->appPath = $this->rootPath . 'app' . DIRECTORY_SEPARATOR;
- $this->runtimePath = $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR;
- if (is_file($this->appPath . 'provider.php')) {
- $this->bind(include $this->appPath . 'provider.php');
- }
- static::setInstance($this);
- $this->instance('app', $this);
- $this->instance('think\Container', $this);
- }
- /**
- * 注册服务
- * @access public
- * @param Service|string $service 服务
- * @param bool $force 强制重新注册
- * @return Service|null
- */
- public function register($service, bool $force = false)
- {
- $registered = $this->getService($service);
- if ($registered && !$force) {
- return $registered;
- }
- if (is_string($service)) {
- $service = new $service($this);
- }
- if (method_exists($service, 'register')) {
- $service->register();
- }
- if (property_exists($service, 'bind')) {
- $this->bind($service->bind);
- }
- $this->services[] = $service;
- }
- /**
- * 执行服务
- * @access public
- * @param Service $service 服务
- * @return mixed
- */
- public function bootService($service)
- {
- if (method_exists($service, 'boot')) {
- return $this->invoke([$service, 'boot']);
- }
- }
- /**
- * 获取服务
- * @param string|Service $service
- * @return Service|null
- */
- public function getService($service)
- {
- $name = is_string($service) ? $service : get_class($service);
- return array_values(array_filter($this->services, function ($value) use ($name) {
- return $value instanceof $name;
- }, ARRAY_FILTER_USE_BOTH))[0] ?? null;
- }
- /**
- * 开启应用调试模式
- * @access public
- * @param bool $debug 开启应用调试模式
- * @return $this
- */
- public function debug(bool $debug = true)
- {
- $this->appDebug = $debug;
- return $this;
- }
- /**
- * 是否为调试模式
- * @access public
- * @return bool
- */
- public function isDebug(): bool
- {
- return $this->appDebug;
- }
- /**
- * 设置应用命名空间
- * @access public
- * @param string $namespace 应用命名空间
- * @return $this
- */
- public function setNamespace(string $namespace)
- {
- $this->namespace = $namespace;
- return $this;
- }
- /**
- * 获取应用类库命名空间
- * @access public
- * @return string
- */
- public function getNamespace(): string
- {
- return $this->namespace;
- }
- /**
- * 获取框架版本
- * @access public
- * @return string
- */
- public function version(): string
- {
- return static::VERSION;
- }
- /**
- * 获取应用根目录
- * @access public
- * @return string
- */
- public function getRootPath(): string
- {
- return $this->rootPath;
- }
- /**
- * 获取应用基础目录
- * @access public
- * @return string
- */
- public function getBasePath(): string
- {
- return $this->rootPath . 'app' . DIRECTORY_SEPARATOR;
- }
- /**
- * 获取当前应用目录
- * @access public
- * @return string
- */
- public function getAppPath(): string
- {
- return $this->appPath;
- }
- /**
- * 设置应用目录
- * @param string $path 应用目录
- */
- public function setAppPath(string $path)
- {
- $this->appPath = $path;
- }
- /**
- * 获取应用运行时目录
- * @access public
- * @return string
- */
- public function getRuntimePath(): string
- {
- return $this->runtimePath;
- }
- /**
- * 设置runtime目录
- * @param string $path 定义目录
- */
- public function setRuntimePath(string $path): void
- {
- $this->runtimePath = $path;
- }
- /**
- * 获取核心框架目录
- * @access public
- * @return string
- */
- public function getThinkPath(): string
- {
- return $this->thinkPath;
- }
- /**
- * 获取应用配置目录
- * @access public
- * @return string
- */
- public function getConfigPath(): string
- {
- return $this->rootPath . 'config' . DIRECTORY_SEPARATOR;
- }
- /**
- * 获取配置后缀
- * @access public
- * @return string
- */
- public function getConfigExt(): string
- {
- return $this->configExt;
- }
- /**
- * 获取应用开启时间
- * @access public
- * @return float
- */
- public function getBeginTime(): float
- {
- return $this->beginTime;
- }
- /**
- * 获取应用初始内存占用
- * @access public
- * @return integer
- */
- public function getBeginMem(): int
- {
- return $this->beginMem;
- }
- /**
- * 初始化应用
- * @access public
- * @return $this
- */
- public function initialize()
- {
- $this->initialized = true;
- $this->beginTime = microtime(true);
- $this->beginMem = memory_get_usage();
- // 加载环境变量
- if (is_file($this->rootPath . '.env')) {
- $this->env->load($this->rootPath . '.env');
- }
- $this->configExt = $this->env->get('config_ext', '.php');
- $this->debugModeInit();
- // 加载全局初始化文件
- $this->load();
- // 加载框架默认语言包
- $langSet = $this->lang->defaultLangSet();
- $this->lang->load($this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $langSet . '.php');
- // 加载应用默认语言包
- $this->loadLangPack($langSet);
- // 监听AppInit
- $this->event->trigger(AppInit::class);
- date_default_timezone_set($this->config->get('app.default_timezone', 'Asia/Shanghai'));
- // 初始化
- foreach ($this->initializers as $initializer) {
- $this->make($initializer)->init($this);
- }
- return $this;
- }
- /**
- * 是否初始化过
- * @return bool
- */
- public function initialized()
- {
- return $this->initialized;
- }
- /**
- * 加载语言包
- * @param string $langset 语言
- * @return void
- */
- public function loadLangPack($langset)
- {
- if (empty($langset)) {
- return;
- }
- // 加载系统语言包
- $files = glob($this->appPath . 'lang' . DIRECTORY_SEPARATOR . $langset . '.*');
- $this->lang->load($files);
- // 加载扩展(自定义)语言包
- $list = $this->config->get('lang.extend_list', []);
- if (isset($list[$langset])) {
- $this->lang->load($list[$langset]);
- }
- }
- /**
- * 引导应用
- * @access public
- * @return void
- */
- public function boot(): void
- {
- array_walk($this->services, function ($service) {
- $this->bootService($service);
- });
- }
- /**
- * 加载应用文件和配置
- * @access protected
- * @return void
- */
- protected function load(): void
- {
- $appPath = $this->getAppPath();
- if (is_file($appPath . 'common.php')) {
- include_once $appPath . 'common.php';
- }
- include_once $this->thinkPath . 'helper.php';
- $configPath = $this->getConfigPath();
- $files = [];
- if (is_dir($configPath)) {
- $files = glob($configPath . '*' . $this->configExt);
- }
- foreach ($files as $file) {
- $this->config->load($file, pathinfo($file, PATHINFO_FILENAME));
- }
- if (is_file($appPath . 'event.php')) {
- $this->loadEvent(include $appPath . 'event.php');
- }
- if (is_file($appPath . 'service.php')) {
- $services = include $appPath . 'service.php';
- foreach ($services as $service) {
- $this->register($service);
- }
- }
- }
- /**
- * 调试模式设置
- * @access protected
- * @return void
- */
- protected function debugModeInit(): void
- {
- // 应用调试模式
- if (!$this->appDebug) {
- $this->appDebug = $this->env->get('app_debug') ? true : false;
- ini_set('display_errors', 'Off');
- }
- if (!$this->runningInConsole()) {
- //重新申请一块比较大的buffer
- if (ob_get_level() > 0) {
- $output = ob_get_clean();
- }
- ob_start();
- if (!empty($output)) {
- echo $output;
- }
- }
- }
- /**
- * 注册应用事件
- * @access protected
- * @param array $event 事件数据
- * @return void
- */
- public function loadEvent(array $event): void
- {
- if (isset($event['bind'])) {
- $this->event->bind($event['bind']);
- }
- if (isset($event['listen'])) {
- $this->event->listenEvents($event['listen']);
- }
- if (isset($event['subscribe'])) {
- $this->event->subscribe($event['subscribe']);
- }
- }
- /**
- * 解析应用类的类名
- * @access public
- * @param string $layer 层名 controller model ...
- * @param string $name 类名
- * @return string
- */
- public function parseClass(string $layer, string $name): string
- {
- $name = str_replace(['/', '.'], '\\', $name);
- $array = explode('\\', $name);
- $class = Str::studly(array_pop($array));
- $path = $array ? implode('\\', $array) . '\\' : '';
- return $this->namespace . '\\' . $layer . '\\' . $path . $class;
- }
- /**
- * 是否运行在命令行下
- * @return bool
- */
- public function runningInConsole()
- {
- return php_sapi_name() === 'cli' || php_sapi_name() === 'phpdbg';
- }
- /**
- * 获取应用根目录
- * @access protected
- * @return string
- */
- protected function getDefaultRootPath(): string
- {
- $path = dirname(dirname(dirname(dirname($this->thinkPath))));
- return $path . DIRECTORY_SEPARATOR;
- }
- }
|