当前位置: 首页 > 后端技术 > PHP

从bin-swoft入手,阅读Swoft框架源码(一)--应用初始化

时间:2023-03-30 01:04:11 PHP

bean/swoft中的代码如下://导入bootstrap.php文件//其实bootstrap.php只做了一件事:import/vendor/autoload.php//autoload.php加载项目中的库类//Bootstraprequire_once__DIR__。'/bootstrap.php';//设置最大协程数SwooleCoroutine::set(['max_coroutine'=>300000,]);//实例化应用//调用应用的run方法执行应用//run方法在Swoft\Contract\ApplicationInterface中声明//在Swoft\SwoftApplication中实现//Runapplication(newAppApplication())->run();AppApplication的实现非常简单:classApplicationextendsSwoftApplication{protectedfunctionbeforeInit():void{parent::beforeInit();//设置时区//你可以初始化phpsetting.date_default_timezone_set('Asia/Shanghai');}/***@returnarray*/publicfunctiongetCLoggerConfig():array{$config=parent::getCLoggerConfig();//False:不要将日志打印到终端//打开控制台输出$config['enable']=true;返回$配置;}}只重写了父类SwoftApplication的beforeInit方法和`getCLoggerConfig方法。所以实例化应用的操作还是在父类SwoftApplication的构造方法中完成的,先看父类的构造方法代码:publicfunction__construct(array$config=[]){//首先是查看当前运行环境//附上查看运行环境的代码//主要检测PHP版本、swoole版本以及是否加载了冲突扩展//检查运行环境envSwoftHelper::checkRuntime();//存储为全局静态属性。//将当前实例保存在Swoft类的静态属性上Swoft::$app=$this;//调用(触发)beforeInit函数(事件)//在Application的beforeInit中,先调用父类的beforeInit//父类在Phar包中检测并定义常量IN_PHAR是否执行//然后在子类中设置当前时区//Beforeinit$this->beforeInit();//初始化控制台记录器//附上日志初始化代码//初始化控制台记录器$this->initCLogger();//这里设置额外的属性,因为没有传递构造参数,所以不会被执行//可以通过数组设置属性if($config){ObjectHelper::init($this,$config);}//初始化应用程序//附上实现代码//初始化应用程序$this->init();//afterInitmethod(event)call(trigger)//如果是phar环境下,会设置runtime目录,不做任何额外操作//初始化后$this->afterInit();}运行时环境检测代码:publicstaticfunctioncheckRuntime(string$minPhp='7.1',string$minSwoole='4.4.1'):void{//检测php版本是否是否大于7.1,抛出RuntimeExceptionif(version_compare(PHP_VERSION,$minPhp,'<')){thrownewRuntimeException('运行服务器需要PHP版本>'.$minPhp.'!currentis'.PHP_VERSION);}//检测swoole扩展是否加载if(!extension_loaded('swoole')){thrownewRuntimeException("运行服务器,需要扩展'swoole'!");}//检测swoole扩展版本是否大于4.4.1是'.SWOOLE_VERSION);}//冲突扩展$conflicts=['blackfire','xdebug','uopz','xhprof','zend','trace',];//遍历冲突的扩展,如果检测到加载则抛出Exceptionforeach($conflictsas$ext){if(extension_loaded($ext)){thrownewRuntimeException("必须关闭'{$ext}'的扩展,否则会影响swoft!");}}}SwoftApplication的beforeInit:protected函数beforeInit():void{//检查pharenv//检查运行环境是否为phar包if(!defined('IN_PHAR')){define('IN_PHAR',false);}}日志初始化代码:privatefunctioninitCLogger():void{//获取日志配置(这里是父类的返回)//[//'name'=>'swoft',//'enable'=>true,//'output'=>true,//'levels'=>'',//'logFile'=>''//]//控制台记录器配置//在子类$中再次将启用设置为trueconfig=$this->getCLoggerConfig();//初始化consolelogger//swoft的CLog使用了monolog,在monolog的基础上//封装了getTrace方法,方便swoole的调试//附上代码//初始化控制台日志CLog::init($config);}CLog::初始化代码:publicstaticfunctioninit(array$config):void{//self::$cLogger不为null表示已经有一个logger,不需要再次初始化if(self::$cLogger!==null){return;}//config配置$name=$config['name']??'';$enable=$config['enable']??真的;$output=$config['输出']??真的;$levels=$config['levels']??'';$logFile=$config['logFile']??'';//这里使用Monolog的LineFormatter作为后续//CEchoHandler和CFileHandler组件$lineFormatter=newLineFormatter();//初始化CEchoHandler并设置$cEchoHandler=newCEchoHandler();$cEchoHandler->setFormatter($lineFormatter);$cEchoHandler->setLevels($levels);$cEchoHandler->setOutput($output);//初始化CFileHandler并设置$cFileHandler=newCFileHandler();$cFileHandler->setFormatter($lineFormatter);$cFileHandler->setLevels($levels);$cFileHandler->setLogFile($logFile);//初始化CLoggerlogger继承自monolog$cLogger=newCLogger();$cLogger->setName($name);$cLogger->setEnable($enable);$cLogger->setHandlers([$cEchoHandler,$cFileHandler]);//将初始化的控制台记录器保存在cLogger属性上self::$cLogger=$cLogger;}应用程序初始化:protectedfunctioninit():void{//初始化系统路径别名//设置基本路径(项目根目录)$这个->findBasePath();//设置并打印@base@app@config@runtime路径别名$this->setSystemAlias();//初始化EnvProcessor、ConfigProcessor、AnnotationProcessor//BeanProcessor、EventProcessor、ConsoleProcessor//这6个处理器内容太多,只有在后续章节真正调用时才初始化。$processors=$this->processors();//初始化当前应用程序的处理器$this->processor=newApplicationProcessor($this);//将之前初始化的处理器交给当前的应用处理器统一管理和调度$this->processor->addFirstProcessor(...$processors);}总结:应用初始化顺序:1.检查运行环境。2.触发预初始化事件。3.初始化控制台记录器。4.初始化应用程序。5.触发后初始化事件。