think-swoole 3.0入门教程(thinkphp 6.0)架构分析 2

栏目: PHP · 发布时间: 4年前

内容简介:ThinkPHP即将迎来最新版本6.0,针对目前越来越流行Swoole,thinkphp也推出了最新的扩展think-swoole 3.0本文主要介绍在ThinkPHP-swoole 3.0当中所用到的沙盒技术。沙盒--顾名思义,所有程序都运行在一个封闭容器当中,得益于更完善的容器技术,在3.0扩展当中沙盒得以大展身手。

前言

ThinkPHP即将迎来最新版本6.0,针对目前越来越流行Swoole,thinkphp也推出了最新的扩展think-swoole 3.0

沙盒

本文主要介绍在ThinkPHP-swoole 3.0当中所用到的沙盒技术。

沙盒--顾名思义,所有程序都运行在一个封闭容器当中,得益于更完善的容器技术,在3.0扩展当中沙盒得以大展身手。

首先,查看沙盒是如何使用的,查看扩展当中Swoole.php,其中的OnRequest函数

public function onRequest($req, $res)
    {
        $this->app->event->trigger('swoole.request');
        
        $this->resetOnRequest();
        
        /** @var Sandbox $sandbox */
        $sandbox = $this->app->make(Sandbox::class);
        $request = $this->prepareRequest($req);
        
        try {
            $sandbox->setRequest($request);
            
            $sandbox->init();
            
            $response = $sandbox->run($request);
            
            $this->sendResponse($sandbox, $response, $res);
        } catch (Throwable $e) {
            try {
                $exceptionResponse = $this->app
                    ->make(Handle::class)
                    ->render($request, $e);
                
                $this->sendResponse($sandbox, $exceptionResponse, $res);
            } catch (Throwable $e) {
                $this->logServerError($e);
            }
        } finally {
            $sandbox->clear();
        }
    }

代码中,从容器中取出沙盒,然后将请求注入到沙盒,并在沙盒中计算并返回结果。最终对沙盒进行清除,那么Sandbox是如何起到沙盒的作用的呢?

//$sandbox->setRequest($request);

    public function setRequest(Request $request)
    {
        Context::setData('_request', $request);
        
        return $this;
    }

上述代码将请求注入到了沙盒内,这里又多出一个Context,那么这个类又是做什么的呢?为何不在沙盒内整个属性来存储呢?这个我们文末在做介绍,我介绍沙盒。

//$sandbox->init();
     public function init()
    {
        if (!$this->config instanceof Config) {
            throw new RuntimeException('Please initialize after setting base app.');
        }
        
        $this->setInstance($app = $this->getApplication());
        $this->resetApp($app);
    }

最主要的环节也就是这里了,看到这里就明白沙盒为何称之为沙盒了。由于tp6是基于容器创建和销毁资源的,那么各个容器之间是相对隔离的。下面接着看代码

//$this->setInstance($app = $this->getApplication());
 public function getApplication()
    {
        $snapshot = $this->getSnapshot();
        if ($snapshot instanceof Container) {
            return $snapshot;
        }
        
        $snapshot = clone $this->getBaseApp();
        $this->setSnapshot($snapshot);
        
        return $snapshot;
    }

看到什么了吗?clone,复制。这里将容器对象进行了复制,也就是原容器有的对象,这个新容器也有。也就是说每次请求都会创建一个新的环境用于执行和解析,由于容器的隔离性,每个请求都不会和其他请求进行干扰。

至于下面这段代码,看到这里,我觉得您也已经明白了。

$this->resetApp($app);

番外篇

沙盒当中为何会需要Context类呢?看到这个类以后就会明白了,static::getCoroutineId()是获取当前的协程ID,每一个协程都会有一个独一无二的ID,这样通过Context来存一些特殊数据或者对象就不会造成数据混乱。因为只有当前协程才可以读取到该数据。

<?php

namespace think\swoole\coroutine;

use Swoole\Coroutine;
use think\Container;

class Context
{
    /**
     * The app containers in different coroutine environment.
     *
     * @var array
     */
    protected static $apps = [];

    /**
     * The data in different coroutine environment.
     *
     * @var array
     */
    protected static $data = [];

    /**
     * Get app container by current coroutine id.
     */
    public static function getApp()
    {
        return static::$apps[static::getCoroutineId()] ?? null;
    }

    /**
     * Set app container by current coroutine id.
     *
     * @param Container $app
     */
    public static function setApp(Container $app)
    {
        static::$apps[static::getCoroutineId()] = $app;
    }

    /**
     * Get data by current coroutine id.
     *
     * @param string $key
     *
     * @return mixed|null
     */
    public static function getData(string $key)
    {
        return static::$data[static::getCoroutineId()][$key] ?? null;
    }

    /**
     * Set data by current coroutine id.
     *
     * @param string $key
     * @param        $value
     */
    public static function setData(string $key, $value)
    {
        static::$data[static::getCoroutineId()][$key] = $value;
    }

    /**
     * Remove data by current coroutine id.
     *
     * @param string $key
     */
    public static function removeData(string $key)
    {
        unset(static::$data[static::getCoroutineId()][$key]);
    }

    /**
     * Get data keys by current coroutine id.
     */
    public static function getDataKeys()
    {
        return array_keys(static::$data[static::getCoroutineId()] ?? []);
    }

    /**
     * Clear data by current coroutine id.
     */
    public static function clear()
    {
        unset(static::$apps[static::getCoroutineId()]);
        unset(static::$data[static::getCoroutineId()]);
    }

    /**
     * Get current coroutine id.
     */
    public static function getCoroutineId()
    {
        return Coroutine::getuid();
    }
}

以上所述就是小编给大家介绍的《think-swoole 3.0入门教程(thinkphp 6.0)架构分析 2》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Head First Web Design

Head First Web Design

Ethan Watrall、Jeff Siarto / O’Reilly Media, Inc. / 2009-01-02 / USD 49.99

Want to know how to make your pages look beautiful, communicate your message effectively, guide visitors through your website with ease, and get everything approved by the accessibility and usability ......一起来看看 《Head First Web Design》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具