五月天激情丁香,国产精品2019,国产成人精品亚洲2020,国产精品免费视频一区二区三区,开心久久婷婷综合中文字幕,天堂视频在线观看免费完整版

模板引擎

渲染驅(qū)動(dòng)

EasySwoole 引入模板渲染驅(qū)動(dòng)的形式,把需要渲染的數(shù)據(jù),通過協(xié)程客戶端投遞到自定義的同步進(jìn)程中進(jìn)行渲染并返回結(jié)果。為何要如此處理,原因在于,市面上的一些模板引擎在 Swoole 協(xié)程下存在變量安全問題。例如以下流程:

  • request A reached, static A assign requestA-data
  • compiled template
  • write compiled template (yield current coroutine)
  • request B reached,static A assign requestB-data
  • render static A data into complied template file

以上流程我們可以發(fā)現(xiàn),A 請(qǐng)求的數(shù)據(jù),被 B 請(qǐng)求給污染了。為了解決該問題,EasySwoole 引入模板渲染驅(qū)動(dòng)模式。

組件要求

  • easyswoole/spl: ^1.0
  • easyswoole/component: ^2.0

安裝方法

composer require easyswoole/template

倉(cāng)庫(kù)地址

easyswoole/template

基礎(chǔ)實(shí)現(xiàn)原理講解

實(shí)現(xiàn)渲染引擎

<?php
class R implements \EasySwoole\Template\RenderInterface
{
    public function render(string $template, ?array $data = null, ?array $options = null): ?string
    {
        return 'todo some thing';
    }

    public function onException(\Throwable $throwable, $arg): string
    {
        return $throwable->getMessage();
    }
}

舊版本 Template (1.1.0 之前版本) 實(shí)現(xiàn)渲染引擎如下:

<?php
class R implements \EasySwoole\Template\RenderInterface
{
    public function render(string $template, ?array $data = [], ?array $options = []):?string
    {
        return 'todo some thing';
    }

    public function afterRender(?string $result, string $template, array $data = [], array $options = [])
    {
        // TODO: Implement afterRender() method.
    }

    public function onException(Throwable $throwable, $arg):string
    {
        return $throwable->getMessage();
    }
}

在自定義 HTTP 服務(wù)中調(diào)用渲染引擎

<?php
require_once __DIR__ . '/vendor/autoload.php';

class MyRender implements \EasySwoole\Template\RenderInterface
{

    public function render(string $template, ?array $data = null, ?array $options = null): ?string
    {
        return "your template is {$template} and data is " . json_encode($data);
    }

    public function onException(\Throwable $throwable, $arg): string
    {
        return $throwable->getTraceAsString();
    }
}

$renderConfig = \EasySwoole\Template\Render::getInstance()->getConfig();

/*
 * 可選配置
$renderConfig->setTempDir(getcwd()); // 設(shè)置 渲染引擎驅(qū)動(dòng) Socket 存放目錄,默認(rèn)為 getcwd()
$renderConfig->setTimeout(3); // 設(shè)置 超時(shí)時(shí)間,默認(rèn)為 3s,不建議修改
$renderConfig->setServerName('EasySwoole'); // 設(shè)置 渲染引擎驅(qū)動(dòng)服務(wù)名稱,不建議修改
$renderConfig->setWorkerNum(3); // 設(shè)置 渲染引擎服務(wù)工作進(jìn)程數(shù),默認(rèn)為 3,不建議修改
 */

$renderConfig->setRender(new MyRender()); // 設(shè)置 渲染引擎

$http = new swoole_http_server("0.0.0.0", 9501);
$http->on("request", function ($request, $response) {
    $ret = \EasySwoole\Template\Render::getInstance()->render('index.html', ['easyswoole' => 'hello']);
    $response->end($ret);
});

// 調(diào)用渲染引擎
\EasySwoole\Template\Render::getInstance()->attachServer($http);

$http->start();

舊版本 Template 組件(1.1.0 之前)在自定義 HTTP 服務(wù)中調(diào)用渲染引擎時(shí),實(shí)現(xiàn)渲染引擎接口的方法有些許不同,詳細(xì)請(qǐng)看上文實(shí)現(xiàn)渲染引擎。

重啟渲染引擎

由于某些模板引擎會(huì)緩存模板文件,導(dǎo)致可能出現(xiàn)以下情況:

  • 用戶 A 請(qǐng)求 1.tpl 返回 'a'
  • 開發(fā)者修改了 1.tpl 的數(shù)據(jù),改成了 'b'
  • 用戶 B、C、D 在之后的請(qǐng)求中,可能會(huì)出現(xiàn) 'a'、'b'兩種不同的值

那是因?yàn)槟0逡嬉呀?jīng)緩存了 A 所在進(jìn)程的文件,導(dǎo)致后面的請(qǐng)求如果也分配到了 A 的進(jìn)程,就會(huì)獲取到緩存的值

解決方案如下:

  • 1: 重啟 EasySwoole 服務(wù),即可解決
  • 2: 模板渲染引擎實(shí)現(xiàn)了重啟方法 restartWorker,直接調(diào)用即可
Render::getInstance()->restartWorker();

用戶可以根據(jù)自己的邏輯,自行調(diào)用 restartWorker 方法進(jìn)行重啟。

重啟渲染引擎使用示例

例如:用戶可以在控制器中新增 reload 方法重啟渲染引擎:

1、實(shí)現(xiàn)自定義渲染引擎,新建 App\RenderDriver\MyRender.php 文件

<?php

namespace App\RenderDriver;

class MyRender implements \EasySwoole\Template\RenderInterface
{
    public function render(string $template, ?array $data = null, ?array $options = null): ?string
    {
        return "your template is {$template} and data is " . json_encode($data);
    }

    public function onException(\Throwable $throwable, $arg): string
    {
        return $throwable->getTraceAsString();
    }
}

舊版本 Template 組件(1.1.0 之前)實(shí)現(xiàn)自定義渲染引擎接口的方法和最新穩(wěn)定版本有些許不同,詳細(xì)請(qǐng)看上文。

2、注冊(cè)渲染引擎服務(wù)

<?php

namespace EasySwoole\EasySwoole;

use EasySwoole\EasySwoole\AbstractInterface\Event;
use EasySwoole\EasySwoole\Swoole\EventRegister;
use EasySwoole\Template\Render;

class EasySwooleEvent implements Event
{
    public static function initialize()
    {
        date_default_timezone_set('Asia/Shanghai');
    }

    public static function mainServerCreate(EventRegister $register)
    {
        $renderConfig = \EasySwoole\Template\Render::getInstance()->getConfig();

        /*
         * 可選配置
        $renderConfig->setTempDir(getcwd()); // 設(shè)置 渲染引擎驅(qū)動(dòng) Socket 存放目錄,默認(rèn)為 getcwd()
        $renderConfig->setTimeout(3); // 設(shè)置 超時(shí)時(shí)間,默認(rèn)為 3s,不建議修改
        $renderConfig->setServerName('EasySwoole'); // 設(shè)置 渲染引擎驅(qū)動(dòng)服務(wù)名稱,不建議修改
        $renderConfig->setWorkerNum(3); // 設(shè)置 渲染引擎服務(wù)工作進(jìn)程數(shù),默認(rèn)為 3,不建議修改
         */

        $renderConfig->setRender(new \App\RenderDriver\MyRender());
        Render::getInstance()->attachServer(ServerManager::getInstance()->getSwooleServer());
    }
}

3、在控制器中新增 reload 方法重啟渲染引擎

<?php

namespace App\HttpController;

use EasySwoole\Http\AbstractInterface\Controller;
use EasySwoole\Template\Render;

class Index extends Controller
{
    public function index()
    {
        $this->response()->write(Render::getInstance()->render('index.tpl', [
            'user' => 'easyswoole',
            'time' => time()
        ]));
    }

    public function reload()
    {
        Render::getInstance()->restartWorker();
        $this->response()->write('restart worker success!');
    }
}

運(yùn)行結(jié)果:訪問 http://127.0.0.1:9501/ (示例請(qǐng)求地址) 即可看到運(yùn)行結(jié)果: your template is index.tpl and data is {"user":"easyswoole","time":1613659221},然后訪問 http://127.0.0.1:9501/reload (示例請(qǐng)求地址) 即可重啟渲染引擎,看到運(yùn)行結(jié)果 restart worker success!

使用示例(在 EasySwoole 中使用)

使用 Smarty 渲染

引入Smarty

composer require smarty/smarty

實(shí)現(xiàn)渲染引擎

新建 \App\RenderDriver\Smarty.php,內(nèi)容如下:

<?php

namespace App\RenderDriver;

use EasySwoole\Template\RenderInterface;

class Smarty implements RenderInterface
{
    private $smarty;

    function __construct()
    {
        $temp = sys_get_temp_dir();
        $this->smarty = new \Smarty();
        $this->smarty->setTemplateDir(EASYSWOOLE_ROOT . '/App/View/');
        $this->smarty->setCacheDir("{$temp}/smarty/cache/");
        $this->smarty->setCompileDir("{$temp}/smarty/compile/");
    }

    public function render(string $template, ?array $data = null, ?array $options = null): ?string
    {
        foreach ($data as $key => $item) {
            $this->smarty->assign($key, $item);
        }
        return $this->smarty->fetch($template, $cache_id = null, $compile_id = null, $parent = null, $display = false,
            $merge_tpl_vars = true, $no_output_filter = false);
    }

    public function onException(\Throwable $throwable, $arg): string
    {
        $msg = "{$throwable->getMessage()} at file:{$throwable->getFile()} line:{$throwable->getLine()}";
        trigger_error($msg);
        return $msg;
    }
}

舊版本 Template 組件(1.1.0 之前)實(shí)現(xiàn)渲染引擎接口的方法和最新穩(wěn)定版本有些許不同,詳細(xì)請(qǐng)看上文。Template 1.1.0 之前版本實(shí)現(xiàn)如下:

<?php
namespace App\RenderDriver;

use EasySwoole\Template\RenderInterface;

class Smarty implements RenderInterface
{
    private $smarty;

    function __construct()
    {
        $temp = sys_get_temp_dir();
        $this->smarty = new \Smarty();
        $this->smarty->setTemplateDir(EASYSWOOLE_ROOT . '/App/View/');
        $this->smarty->setCacheDir("{$temp}/smarty/cache/");
        $this->smarty->setCompileDir("{$temp}/smarty/compile/");
    }

    public function render(string $template, ?array $data = [], ?array $options = []): ?string
    {
        foreach ($data as $key => $item) {
            $this->smarty->assign($key, $item);
        }
        return $this->smarty->fetch($template, $cache_id = null, $compile_id = null, $parent = null, $display = false,
            $merge_tpl_vars = true, $no_output_filter = false);
    }

    public function afterRender(?string $result, string $template, array $data = [], array $options = [])
    {

    }

    public function onException(\Throwable $throwable, $arg): string
    {
        $msg = "{$throwable->getMessage()} at file:{$throwable->getFile()} line:{$throwable->getLine()}";
        trigger_error($msg);
        return $msg;
    }
}

在 EasySwoole 的 HTTP 服務(wù)中調(diào)用

首先在 EasySwoole 全局事件 EasySwooleEvent.phpmainServerCreate 事件中注冊(cè)渲染引擎服務(wù),注冊(cè)示例代碼如下:

<?php

namespace EasySwoole\EasySwoole;

use EasySwoole\EasySwoole\AbstractInterface\Event;
use EasySwoole\EasySwoole\Swoole\EventRegister;

class EasySwooleEvent implements Event
{
    public static function initialize()
    {
        date_default_timezone_set('Asia/Shanghai');
    }

    public static function mainServerCreate(EventRegister $register)
    {
        // 獲取 Render 配置
        $renderConfig = \EasySwoole\Template\Render::getInstance()->getConfig();

        // [可選配置]
        /*
        $renderConfig->setTimeout(3); // 設(shè)置 超時(shí)時(shí)間,默認(rèn)為 3s,不建議修改
        $renderConfig->setServerName('EasySwoole'); // 設(shè)置 渲染引擎驅(qū)動(dòng)服務(wù)名稱,不建議修改
        $renderConfig->setWorkerNum(3); // 設(shè)置 渲染引擎服務(wù)工作進(jìn)程數(shù),默認(rèn)為 3,不建議修改
         */

        // 設(shè)置 渲染引擎模板驅(qū)動(dòng)
        $renderConfig->setRender(new \App\RenderDriver\Smarty());

        // 設(shè)置 渲染引擎進(jìn)程 Socket 存放目錄,默認(rèn)為 getcwd()
        $renderConfig->setTempDir(EASYSWOOLE_TEMP_DIR);

        // 注冊(cè)進(jìn)程到 EasySwoole 主服務(wù)
        \EasySwoole\Template\Render::getInstance()->attachServer(\EasySwoole\EasySwoole\ServerManager::getInstance()->getSwooleServer());
    }
}

在控制器層響應(yīng)(使用示例代碼如下):

首先新建 App\View\custom.html,內(nèi)容如下:

{$name}

在控制器中進(jìn)行調(diào)用:

<?php

namespace App\HttpController;

use EasySwoole\Http\AbstractInterface\Controller;

class Index extends Controller
{
    public function index()
    {
        $this->response()->write(\EasySwoole\Template\Render::getInstance()->render('custom.html', ['name' => 'Welcome To Use EasySwoole ^_^!']));
    }
}

運(yùn)行結(jié)果:?jiǎn)?dòng)服務(wù),訪問 http://127.0.0.1:9501,即可看到運(yùn)行結(jié)果:Welcome To Use EasySwoole ^_^!

支持常用的模板引擎

下面列舉一些常用的模板引擎包方便引入使用:

smarty/smarty

Smarty 是一個(gè)使用 PHP 寫出來的模板引擎,是目前業(yè)界最著名的 PHP 模板引擎之一。

引入方法

composer require smarty/smarty=~3.1

league/plates

使用原生 PHP 語(yǔ)法的非編譯型模板引擎,更低的學(xué)習(xí)成本和更高的自由度。

引入方法

composer require league/plates=3.*

duncan3dc/blade

Laravel 框架使用的模板引擎

引入方法

composer require duncan3dc/blade=^4.5

topthink/think-template

ThinkPHP 框架使用的模板引擎

引入方法

composer require topthink/think-template

如果用戶想要在 EasySwoole 框架中使用以上模板引擎,具體使用示例可以查看Template 使用示例 或者 Template 組件單元測(cè)試用例。上文中講述了使用 Smarty 模板引擎的使用示例,其他模板引擎的使用方法大致類似。

常見問題

注冊(cè)渲染引擎失敗,出現(xiàn) UnixSocket bind 失敗

  • 報(bào)錯(cuò)結(jié)果類似如下:
PHP Fatal error:  Uncaught EasySwoole\Component\Process\Exception: EasySwoole\Template\RenderWorker bind /work/EasySwoole.Render.Worker.0.sock fail case Operation not permitted in /work/vendor/easyswoole/component/src/Process/Socket/AbstractUnixProcess.php:32
  • 失敗原因:部分 vargrant 服務(wù)器或 Docker 服務(wù)器沒有權(quán)限創(chuàng)建 UnixSocket,導(dǎo)致注冊(cè)渲染引擎失敗。
  • 解決方案:注冊(cè)渲染引擎時(shí),設(shè)置渲染引擎驅(qū)動(dòng)進(jìn)程 Socket 存放目錄為 '/Tmp'。示例代碼如下:
<?php

namespace EasySwoole\EasySwoole;

use EasySwoole\EasySwoole\AbstractInterface\Event;
use EasySwoole\EasySwoole\Swoole\EventRegister;

class EasySwooleEvent implements Event
{
    public static function initialize()
    {
        date_default_timezone_set('Asia/Shanghai');
    }

    public static function mainServerCreate(EventRegister $register)
    {
        // 獲取 Render 配置
        $renderConfig = \EasySwoole\Template\Render::getInstance()->getConfig();
        // 設(shè)置 渲染引擎模板驅(qū)動(dòng)
        $renderConfig->setRender(new \App\RenderDriver\Smarty());

        ###  設(shè)置 渲染引擎進(jìn)程 Socket 存放目錄為 '/Tmp'  ###
        $renderConfig->setTempDir('/Tmp');

        // 注冊(cè)進(jìn)程到 EasySwoole 主服務(wù)
        \EasySwoole\Template\Render::getInstance()->attachServer(\EasySwoole\EasySwoole\ServerManager::getInstance()->getSwooleServer());
    }
}
主站蜘蛛池模板: 国产一区二区三区在线观看精品 | 国内精品一级毛片免费看 | 韩国美女福利专区一区二区 | 色婷婷免费视频 | 日韩欧美在线一级一中文字暮 | α片免费 | 免费萌白酱国产一区二区三区 | 国产欧美一区二区三区在线 | 高清不卡一区 | 8888四色奇米在线观看不卡 | 97精品高清一区二区三区 | 五月婷婷六月丁香激情 | 国产日韩欧美在线播放 | 理论片 国产台湾在线 | 国产一级淫片免费视频 | 成人欧美精品一区二区不卡 | 毛片在线观看网站 | 国产一级毛片免 | 国产在线精品一区二区 | 欧美综合激情 | 善良的嫂子3电影 | 人成电影网在线观看免费 | 日韩国产在线观看 | 日本视频免费播放 | 久久这里只有精品免费看青草 | 97在线视频免费观看费观看 | 99精品国产高清一区二区麻豆 | 99热这里只有精品一区二区三区 | www.亚洲视频.com | 五月天婷婷综合网 | 日本深夜福利视频 | 大陆毛片 | 嫩草影院免费在线观看 | 欧美性猛交99久久久久99 | 久久精品人人爽人人爽快 | 爽爽影院在线看 | 少女免费观看完整版 | 欧美无遮挡一区二区三区 | 九七视频在线观看 | 国产色视频一区 | 国产蜜臀|