惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
Webroot Blog
Webroot Blog
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
雷峰网
雷峰网
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog
美团技术团队
云风的 BLOG
云风的 BLOG
IT之家
IT之家
S
Secure Thoughts
U
Unit 42
G
GRAHAM CLULEY
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
N
News and Events Feed by Topic
The Cloudflare Blog
月光博客
月光博客
V
Visual Studio Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Schneier on Security
Schneier on Security
O
OpenAI News
Hacker News - Newest:
Hacker News - Newest: "LLM"
P
Privacy International News Feed
The Hacker News
The Hacker News
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
Tailwind CSS Blog
SecWiki News
SecWiki News
M
MIT News - Artificial intelligence
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Simon Willison's Weblog
Simon Willison's Weblog
Stack Overflow Blog
Stack Overflow Blog
爱范儿
爱范儿
Last Week in AI
Last Week in AI
C
Check Point Blog
D
Docker
Scott Helme
Scott Helme
Engineering at Meta
Engineering at Meta
博客园_首页
W
WeLiveSecurity
MongoDB | Blog
MongoDB | Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
Vulnerabilities – Threatpost
D
Darknet – Hacking Tools, Hacker News & Cyber Security
J
Java Code Geeks
NISL@THU
NISL@THU
S
Security Affairs
C
Cybersecurity and Infrastructure Security Agency CISA
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

流动

对口型视频合成方案对比:Wav2Lip、VideoReTalking 与 MuseTalk 2026 音色克隆方案对比:IndexTTS-2、CosyVoice、GPT-SoVITS、Fish Speech、VoxCPM 部署与实测 AI Agent折腾记(OpenClaw / Hermes Agent) 我的2025年 大连之行 回家收麦 六一儿童节爬长城 Golang database/sql 数据库断线自动重连机制解析 Golang默认Http Client导致的cannot assign requested address错误 清明踏春,爬山看海 购入小牛G400T电动车 北京的三月飞雪 wrenAI本地LLM模型部署 天津一日游 2024年终总结 停止使用staticfile.org服务 使用 ImageMagick 自动添加水印,保护图片版权 如何注册一个.sol域名 奥森公园半日游 昌平42公里骑行绿道打卡 十月一日爬慕田峪长城 当Hugo遇上AVIF,优化图片加载 博客被恶意镜像 Github Pages 部署流程解析 搭建个人锻炼页面 你好 Follow 中秋爬山 Google Adsense的审核之旅 让你的IPFS站点持久在线:接入Filebase的Names(IPNS)服务 一次简短的青岛之行 解决 "undeclared name: any (requires version go1.18 or later)" 编译错误 搭建自托管IPFS Gateway服务,替代Cloudflare的IPFS Gateway 302跳转的跨域问题(CORS) GORM增加sqlcommenter特性 源码分析:GORM是如何生成sql的 工银亚洲网银密码重置 加速Cloudflare访问 2023年终总结 2023年12月北京暴雪记录 使用Hugo实现响应式和优化的图片 加速Google Analytics 使用Google Indexing API加速博客收录 在Netlify上部署Twikoo评论系统 利用Github Actions定时抓取微博 北大口腔牙周刮治记录 故乡回忆之旅 解决Golang使用go get安装包后找不到可执行文件的问题 修正Hugo的JSON Feed格式 我的学车之路 将博客部署到星际文件系统(IPFS) 新冠疫情后的第一个春节 第一次清理键盘 2022年终总结 去掉Cloudflare烦人的email-decode.min.js请求 累计布局偏移修复方案改进 —— 自动生成图片宽高 优化博客的累计布局偏移(CLS)问题 将博客部署到Cloudflare Pages 奥林匹克公园向日葵之旅 记第二次洗牙 记录2022年海淀幼升小 Golang解析json的一个问题 疫情下的生活 整理下博客的一些调整 疫情下的五一假期 自己动手,更换thinkpad x1硬盘 二刷百望山 带娃游颐和园 博客架构说明 难得的清明假期 十一年的等待,终于拿到了liudon.com域名 被隔离的一周 mysql中字符串和整型自动转换的问题 一次惊心动魄的Mysql更新操作 如何在北京公积金网站上修改婚姻状况 PHP7.2编译安装后没有php.ini文件的问题 检测网站支持的SSL/TLS协议版本 记一次难忘的手术经历 十一假期经历 Swoft 框架运行分析(五) —— ConsoleProcessor模块分析 Swoft 框架运行分析(四) —— EventProcessor模块分析 一个git submodule update引发的问题 一个Curl的耗时长的问题 Swoft 框架运行分析(三) —— BeanProcessor模块分析 Swoft 框架运行分析(二) —— AnnotationProcessor模块分析 BCMath 与 科学计数 Flink Could Not Resolve Resourcemanager Address 解决Sublime Text安装包时"There Are No Packages Available for Installation"的报错 关于本站 2019,新开始
Swoft 框架运行分析(一)
Liudon · 2019-08-29 · via 流动

Swoft 是一款基于 Swoole 扩展实现的 PHP 微服务协程框架。

以前一直都是用的原生swoole框架,最近有时间研究了下衍生的Swoft框架。

刚开始看的时候,感觉自己像个原始人,完全看不懂。

官方文档没有介绍Swoft的实现,网上的一些文章跟当前版本代码已经不一致了。

自己花了一周时间,终于梳理清楚了,看完更觉得自己是个原始人了。

使用的框架组件版本为:

swoft-2.0.5
swoft-component-2.0.5

这里以Swoft启动http server为例。

执行上述命令,启动http server。

这里执行的是bin/swoft文件。

#!/usr/bin/env php
<?php declare(strict_types=1);

// Bootstrap
require_once __DIR__ . '/bootstrap.php';

Swoole\Coroutine::set([
    'max_coroutine' => 300000,
]);

// Run application
(new \App\Application())->run();

这里引入bootstrap.php文件,引入composer自动加载文件。

<?php
// Composer autoload
require_once dirname(__DIR__) . '/vendor/autoload.php';

然后执行Swoft\App\Application类下的run方法。

<?php declare(strict_types=1);

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();

        date_default_timezone_set('Asia/Shanghai');
    }
}

这里继承了Swoft\SwoftApplication类,这里只粘贴了部分代码。

/**
 * Swoft application
 *
 * @since 2.0
 */
class SwoftApplication implements SwoftInterface, ApplicationInterface
{

    /**
     * Class constructor.
     *
     * @param array $config
     */
    public function __construct(array $config = [])
    {
        // Check runtime env
        SwoftHelper::checkRuntime();

        // Storage as global static property.
        Swoft::$app = $this;

        // Before init
        $this->beforeInit();

        // Init console logger
        $this->initCLogger();

        // Can setting properties by array
        if ($config) {
            ObjectHelper::init($this, $config);
        }

        // Init application
        $this->init();

        CLog::info('Project path is <info>%s</info>', $this->basePath);

        // After init
        $this->afterInit();
    }

    protected function init(): void
    {
        // Init system path aliases
        $this->findBasePath();
        $this->setSystemAlias();

        $processors = $this->processors();

        $this->processor = new ApplicationProcessor($this);
        $this->processor->addFirstProcessor(...$processors);
    }

    /**
     * Run application
     */
    public function run(): void
    {
        if (!$this->beforeRun()) {
            return;
        }

        $this->processor->handle();
    }

    /**
     * @return ProcessorInterface[]
     */
    protected function processors(): array
    {
        return [
            new EnvProcessor($this),
            new ConfigProcessor($this),
            new AnnotationProcessor($this),
            new BeanProcessor($this),
            new EventProcessor($this),
            new ConsoleProcessor($this),
        ];
    }

__construct方法里检查运行环境,初始化日志组件,然后调用了init方法。

init方法里声明了processor对象。

processors方法定义了Swoft框架的6个Processor对象。

run方法里直接调用processor对象的handler方法。

<?php

namespace Swoft\Processor;

use Swoft\Stdlib\Helper\ArrayHelper;
use function get_class;

/**
 * Application processor
 * @since 2.0
 */
class ApplicationProcessor extends Processor
{
    /**
     * @var ProcessorInterface[]
     */
    private $processors = [];

    /**
     * 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;
    }

    /**
     * Add first processor
     *
     * @param Processor[] $processor
     * @return bool
     */
    public function addFirstProcessor(Processor ...$processor): bool
    {
        array_unshift($this->processors, ... $processor);

        return true;
    }

    /**
     * Add last processor
     *
     * @param Processor[] $processor
     *
     * @return bool
     */
    public function addLastProcessor(Processor ...$processor): bool
    {
        array_push($this->processors, ... $processor);

        return true;
    }

    /**
     * Add processors
     *
     * @param int         $index
     * @param Processor[] $processors
     *
     * @return bool
     */
    public function addProcessor(int $index, Processor  ...$processors): bool
    {
        ArrayHelper::insert($this->processors, $index, ...$processors);

        return true;
    }
}

addFirstProcessor方法把process对象赋值给$this->processors

handle方法遍历processors对象,循环执行handle方法。

Swoft的核心逻辑都是靠上面定义的6个Processor模块实现的,接下来一个一个分析。