Easyswoole源码分析-3-Install

10306662-f214ba39a697a21c.png
image.png

1.简介

下载Easyswoole框架后,需要执行php vendor/bin/easyswoole install,接下来介绍一些执行这个命令后具体执行了哪些操作。

10306662-d22c9f56b59d0004.png
image.png

2. 先看CommandRunner类的run方法

核心代码

function run(array $args):?string
    {
        ·
        ·
        ·
        // 如果执行命令为install
        }else if($command != 'install'){
            //预先加载配置(dev为线上配置,produce为开发配置)
            if(in_array('produce',$args)){
                Core::getInstance()->setIsDev(false);
            }
            // 主要完成的操作1
            Core::getInstance()->initialize();
        }
        ·
        ·
        ·
        // 主要完成的操作2(请先阅读前几章)
        return CommandContainer::getInstance()->hook($command,$args);
    }

1.根据install去执行相应操作。
2.根据是否有produce参数来决定是否使用开发|线上配置。
3.执行install类的exec方法。

接下来具体来分析一下代码注释中的操作1和操作2

3.Core::getInstance()->initialize();

知识点

  1. ReflectionClass (反射机制)
  2. 类名|接口名|组合名::class
  3. php7的异常和错误的改变
  4. php spl 扩展的ArrayObject
    5.php预定义常量
    6.设计模式:适配器模式

核心代码

function initialize()
{
        //检查全局文件是否存在.
        $file = EASYSWOOLE_ROOT . '/EasySwooleEvent.php';
        if(file_exists($file)){
            require_once $file;
            try{
                $ref = new \ReflectionClass('EasySwoole\EasySwoole\EasySwooleEvent');
                if(!$ref->implementsInterface(Event::class)){
                    die('global file for EasySwooleEvent is not compatible for EasySwoole\EasySwoole\EasySwooleEvent');
                }
                unset($ref);
            }catch (\Throwable $throwable){
                die($throwable->getMessage());
            }
        }else{
            die('global event file missing');
        }
        //先加载配置文件
        $this->loadEnv();
        //执行了业务处理类的initialize方法
        EasySwooleEvent::initialize();
        //临时文件和Log目录初始化
        $this->sysDirectoryInit();
        //注册错误回调
        $this->registerErrorHandler();
        return $this;
}

接口是否实现

//检查全局文件是否存在.
$file = EASYSWOOLE_ROOT . '/EasySwooleEvent.php';
if(file_exists($file)){
     require_once $file;
     try{
          $ref = new \ReflectionClass('EasySwoole\EasySwoole\EasySwooleEvent');
          if(!$ref->implementsInterface(Event::class)){
                die('global file for EasySwooleEvent is not compatible for EasySwoole\EasySwoole\EasySwooleEvent');
          }
          unset($ref);
         }catch (\Throwable $throwable){
              die($throwable->getMessage());
         }
}else{
      // 如果没有EasySwooleEvent.php 直接die
      die('global event file missing');
}

loadEnv方法

public function loadEnv()
    {
        //加载之前,先清空原来的
        if($this->isDev){
            $file  = EASYSWOOLE_ROOT.'/dev.php';
        }else{
            $file  = EASYSWOOLE_ROOT.'/produce.php';
        }
        Config::getInstance()->loadEnv($file);
    }

Config的loadEnv方法

/**
* $this->conf = new SplArray(); 这里有时间会单独剖析一下一峰大佬写的
* SplArray工具类,这个类继承了spl扩展的ArrayObject,看下上面的知识点应该就能看懂。
*
**/
public function loadEnv(string $file)
{
        if(file_exists($file)){
            $data = require $file;
            // 将ArrayObject对象给conf
            $this->conf->loadArray($data);
        }else{
            throw new \Exception("config file : {$file} is miss");
        }
}

$this->sysDirectoryInit();

我再注释当中解释了过程

private function sysDirectoryInit():void
    {
        //--------------------------------1.创建temp目录-------------------------------
        //创建临时目录    请以绝对路径,不然守护模式运行会有问题
        $tempDir = Config::getInstance()->getConf('TEMP_DIR');
        // 是否具有此配置项
        if(empty($tempDir)){
            // 没有配置则默认路径
            $tempDir = EASYSWOOLE_ROOT.'/Temp';
            // 设置默认路径
            Config::getInstance()->setConf('TEMP_DIR',$tempDir);
        }else{
            // 如果最后一个字符为/则删除
            $tempDir = rtrim($tempDir,'/');
        }
        if(!is_dir($tempDir)){
            // 创建目录
            mkdir($tempDir);
        }
        defined('EASYSWOOLE_TEMP_DIR') or define('EASYSWOOLE_TEMP_DIR',$tempDir);
        //---------------------------------2.创建Log目录------------------------------
        $logDir = Config::getInstance()->getConf('LOG_DIR');
        if(empty($logDir)){
            $logDir = EASYSWOOLE_ROOT.'/Log';
            Config::getInstance()->setConf('LOG_DIR',$logDir);
        }else{
            $logDir = rtrim($logDir,'/');
        }
        if(!is_dir($logDir)){
            mkdir($logDir);
        }
        defined('EASYSWOOLE_LOG_DIR') or define('EASYSWOOLE_LOG_DIR',$logDir);

        //设置默认文件目录值
        Config::getInstance()->setConf('MAIN_SERVER.SETTING.pid_file',$tempDir.'/pid.pid');
        Config::getInstance()->setConf('MAIN_SERVER.SETTING.log_file',$logDir.'/swoole.log');
    }

$this->registerErrorHandler();

具体的你们追下去看吧,写的真的不错,尤其是set_error_handler和register_shutdown_function

private function registerErrorHandler()
    {
        // 显示错误
        ini_set("display_errors", "On");
        // E_STRICT出外的所有错误和警告信息。E_STRICT:启用 PHP 对代码的修改建议,以确保代码具有最佳的互操作性和向前兼容性。
        error_reporting(E_ALL | E_STRICT);
        //---------------------------------1.初始化配置Logger------------------------------
        //初始化配置Logger,install指令的时候这里获取不到logger对象,因此执行new \EasySwoole\Trace\Logger(EASYSWOOLE_LOG_DIR);
        $logger = Di::getInstance()->get(SysConst::LOGGER_HANDLER);
        if(!$logger instanceof LoggerInterface){
            $logger = new \EasySwoole\Trace\Logger(EASYSWOOLE_LOG_DIR);
        }
        // 这里的Logger和\EasySwoole\Trace\Logger不是一个
        Logger::getInstance($logger);
        //---------------------------------2.初始化追踪器------------------------------
        //初始化追踪器
        $trigger = Di::getInstance()->get(SysConst::TRIGGER_HANDLER);
        if(!$trigger instanceof TriggerInterface){
            $display = Config::getInstance()->getConf('DISPLAY_ERROR');
            $trigger = new \EasySwoole\Trace\Trigger(Logger::getInstance(),$display);
        }
        // 这里的Trigger和\EasySwoole\Trace\Trigger 不是一个
        Trigger::getInstance($trigger);
        //---------------------------------3.set_error_handler------------------------------
        //在没有配置自定义错误处理器的情况下,转化为trigger处理
        $errorHandler = Di::getInstance()->get(SysConst::ERROR_HANDLER);
        if(!is_callable($errorHandler)){
            $errorHandler = function($errorCode, $description, $file = null, $line = null){
                $l = new Location();
                $l->setFile($file);
                $l->setLine($line);
                Trigger::getInstance()->error($description,$errorCode,$l);
            };
        }
        set_error_handler($errorHandler);
        //---------------------------------3.register_shutdown_function------------------------------
        $func = Di::getInstance()->get(SysConst::SHUTDOWN_FUNCTION);
        if(!is_callable($func)){
            $func = function (){
                $error = error_get_last();
                if(!empty($error)){
                    $l = new Location();
                    $l->setFile($error['file']);
                    $l->setLine($error['line']);
                    Trigger::getInstance()->error($error['message'],$error['type'],$l);
                }
            };
        }
        register_shutdown_function($func);
    }

3. Install类的exec方法

    file_put_contents(EASYSWOOLE_ROOT . '/easyswoole',file_get_contents(__DIR__.'/../../../bin/easyswoole'));

这里还不知道要干啥,后面用到的时候再说。

核心代码

public function exec(array $args): ?string
    {
        // TODO: Implement exec() method.
        // 输出logo
        echo Utility::easySwooleLog();
        // 更新easyswoole文件
        if(is_file(EASYSWOOLE_ROOT . '/easyswoole')){
            unlink(EASYSWOOLE_ROOT . '/easyswoole');
        }
        // 将easyswoole内容拷贝到__DIR__.'/../../../bin/easyswoole'中,这里我还不知道目的是什么,下面用到后再解释
        file_put_contents(EASYSWOOLE_ROOT . '/easyswoole',file_get_contents(__DIR__.'/../../../bin/easyswoole'));
        // 将下面的文件copy到/../../Resource/下
        Utility::releaseResource(__DIR__ . '/../../Resource/EasySwooleEvent.tpl', EASYSWOOLE_ROOT . '/EasySwooleEvent.php');
        Utility::releaseResource(__DIR__ . '/../../Resource/Config.tpl', EASYSWOOLE_ROOT . '/dev.php');
        Utility::releaseResource(__DIR__ . '/../../Resource/Config.tpl', EASYSWOOLE_ROOT . '/produce.php');
        echo "install success,enjoy! \n";
        return null;
    }

easySwooleLog 方法

虽然没啥逻辑,就当宣传一下easyswoole吧

public static function easySwooleLog()
    {
        return <<<LOGO
  ______                          _____                              _
 |  ____|                        / ____|                            | |
 | |__      __ _   ___   _   _  | (___   __      __   ___     ___   | |   ___
 |  __|    / _` | / __| | | | |  \___ \  \ \ /\ / /  / _ \   / _ \  | |  / _ \
 | |____  | (_| | \__ \ | |_| |  ____) |  \ V  V /  | (_) | | (_) | | | |  __/
 |______|  \__,_| |___/  \__, | |_____/    \_/\_/    \___/   \___/  |_|  \___|
                          __/ |
                         |___/

LOGO;
    }

4.相关链接

Easyswoole手册

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值