啟動命令 php bin/swoft http:start
或者 swoftctl run -c http:start
1 入口文件 bin/swoft.php
#!/usr/bin/env php <?php // Bootstrap require_once __DIR__ . '/bootstrap.php'; Swoole\Coroutine::set([ 'max_coroutine' => 300000, ]); // Run application (new \App\Application())->run();
new Application 進入文件 app/Application
<?php declare(strict_types=1); /** * This file is part of Swoft. * * @link https://swoft.org * @document https://swoft.org/docs * @contact group@swoft.org * @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE */ namespace App; use Swoft\SwoftApplication; use function date_default_timezone_set; /** * Class Application * * @since 2.0 */ class Application extends SwoftApplication { protected function beforeInit(): void { parent::beforeInit(); // you can init php setting. date_default_timezone_set('Asia/Shanghai'); // 設置時區 } /** * @return array */ public function getCLoggerConfig(): array { $config = parent::getCLoggerConfig(); // False: Dont print log to terminal $config['enable'] = true; return $config; } }
發現他繼承 SwoftApplication 要執行父類的construct方法
進入 SwoftApplication 發現初始化方法
/**
* Class constructor.
*
* @param array $config
*/
public function __construct(array $config = [])
{
// Check runtime env 檢查運行環境是否符合 php版本 swoole版本
SwoftHelper::checkRuntime();
// Storage as global static property.
Swoft::$app = $this; // 當前對象賦值給
// Before init
$this->beforeInit();
// Init console logger
$this->initCLogger(); //初始化 打印到console界面的日志系統
// Can setting properties by array
if ($config) {
ObjectHelper::init($this, $config); // 初始化配置
}
// Init application
$this->init(); // 真真的初始化
// After init
$this->afterInit(); // 初始化完執行
}
進入 $this->init()
protected function init(): void
{
// Init system path aliases
$this->findBasePath(); // 找到當前基本路徑
$this->setSystemAlias(); // 設置系統別名
$processors = $this->processors(); //重要 實例化幾個進程 返回
$this->processor = new ApplicationProcessor($this); // 實例化$this->processor 也就是當前application運用的屬性 后面會執行他的handel方法
$this->processor->addFirstProcessor(...$processors); // 把第一個processor添加到 $this->processors
}
/**
* @return ProcessorInterface[]
*/
protected function processors(): array
{
return [
new EnvProcessor($this), // 環境
new ConfigProcessor($this), // 配置
new AnnotationProcessor($this), // 注解
new BeanProcessor($this), // bean
new EventProcessor($this), // 事件
new ConsoleProcessor($this),
];
}
$this->processor = new ApplicationProcessor($this);
調用每個process的handel方法
/**
* Handle application processors
*/
public function handle(): bool
{
$disabled = $this->application->getDisabledProcessors();
foreach ($this->processors as $processor) {
$class = get_class($processor);
// If is disabled, skip handle.
if (isset($disabled[$class])) {
continue;
}
$processor->handle();
}
return true;
}
$this->processor->addFirstProcessor(...$processors); // 把這些對象都丟到$this->processors里面
public function addFirstProcessor(Processor ...$processor): bool
{
array_unshift($this->processors, ... $processor);
return true;
}
實例化 基本執行完成,開始run
// Run application
(new \App\Application())->run();
/**
* Run application
*/
public function run(): void
{
try {
if (!$this->beforeRun()) {
return;
}
$this->processor->handle();
} catch (Throwable $e) {
Console::colored(sprintf('%s(code:%d) %s', get_class($e), $e->getCode(), $e->getMessage()), 'red');
Console::colored('Code Trace:', 'comment');
echo $e->getTraceAsString(), "\n";
}
}
調用當前對象的 handle方法
public function handle(): bool
{
$disabled = $this->application->getDisabledProcessors();
foreach ($this->processors as $processor) {
$class = get_class($processor);
// If is disabled, skip handle.
if (isset($disabled[$class])) {
continue;
}
$processor->handle();
}
return true;
}
這個時候 將之前保存到$this->pkrocesssors里面的對象的handle方法執行一遍
初始化完成
string(29) "Swoft\Processor\BeanProcessor"
string(31) "Swoft\Processor\ConfigProcessor"
string(35) "Swoft\Processor\AnnotationProcessor"
string(28) "Swoft\Processor\EnvProcessor"
string(32) "Swoft\Processor\ConsoleProcessor"
代碼位於framwork/processor
比如 執行beanprocessor 下面的handle方法 做了一大堆事情,好像是初始bean化容器 把注解 定義 解析等都掛到container的屬性上去
BeanFactory::addDefinitions($definitions);
BeanFactory::addAnnotations($annotations);
BeanFactory::addParsers($parsers);
BeanFactory::setHandler($handler);
BeanFactory::init();
public static function addAnnotations(array $annotations): void
{
Container::getInstance()->addAnnotations($annotations);
}
public function addAnnotations(array $annotations): void
{
$this->annotations = ArrayHelper::merge($this->annotations, $annotations);
}
<?php declare(strict_types=1);
namespace Swoft\Processor;
use InvalidArgumentException;
use ReflectionException;
use Swoft\Annotation\AnnotationRegister;
use Swoft\Annotation\Exception\AnnotationException;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Bean\BeanFactory;
use Swoft\Bean\Container;
use Swoft\BeanHandler;
use Swoft\Config\Config;
use Swoft\Contract\DefinitionInterface;
use Swoft\Helper\SwoftHelper;
use Swoft\Log\Helper\CLog;
use Swoft\Stdlib\Helper\ArrayHelper;
use function alias;
use function file_exists;
use function get_class;
use function sprintf;
/**
* Class BeanProcessor
*
* @since 2.0
*/
class BeanProcessor extends Processor
{
/**
* Handle bean
*
* @return bool
* @throws ReflectionException
* @throws AnnotationException
*/
public function handle(): bool
{
if (!$this->application->beforeBean()) {
return false;
}
$handler = new BeanHandler();
$definitions = $this->getDefinitions();
$parsers = AnnotationRegister::getParsers();
$annotations = AnnotationRegister::getAnnotations();
BeanFactory::addDefinitions($definitions);
BeanFactory::addAnnotations($annotations);
BeanFactory::addParsers($parsers);
BeanFactory::setHandler($handler);
BeanFactory::init();
$stats = BeanFactory::getStats();
CLog::info('Bean is initialized(%s)', SwoftHelper::formatStats($stats));
/* @var Config $config */
$config = BeanFactory::getBean('config');
CLog::info('Config path is %s', $config->getPath());
if ($configEnv = $config->getEnv()) {
CLog::info('Config env=%s', $configEnv);
} else {
CLog::info('Config env is not setting');
}
return $this->application->afterBean();
}
/**
* Get bean definitions
*
* @return array
*/
private function getDefinitions(): array
{
// Core beans
$definitions = [];
$autoLoaders = AnnotationRegister::getAutoLoaders();
// get disabled loaders by application
$disabledLoaders = $this->application->getDisabledAutoLoaders();
foreach ($autoLoaders as $autoLoader) {
if (!$autoLoader instanceof DefinitionInterface) {
continue;
}
$loaderClass = get_class($autoLoader);
// If the component is disabled by app.
if (isset($disabledLoaders[$loaderClass])) {
CLog::info('Auto loader(%s) is <cyan>DISABLED</cyan>, skip handle it', $loaderClass);
continue;
}
// If the component is disabled by self.
if (!$autoLoader->isEnable()) {
CLog::info('Auto loader(%s) is <cyan>DISABLED</cyan>, skip handle it', $loaderClass);
continue;
}
$definitions = ArrayHelper::merge($definitions, $autoLoader->beans());
}
// Application bean definitions
$beanFile = alias($this->application->getBeanFile());
if (!file_exists($beanFile)) {
throw new InvalidArgumentException(sprintf('The bean config file of %s is not exist!', $beanFile));
}
/** @noinspection PhpIncludeInspection */
$beanDefinitions = require $beanFile;
return ArrayHelper::merge($definitions, $beanDefinitions);
}
}
