亚洲精品成人_精品成人一区_999视频在线播放_免费黄色在线_亚洲成人久久久_久久www免费视频

模板引擎

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

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

  • 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)求給污染了。為了解決該問(wèn)題,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'
  • 開(kāi)發(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é)果:訪問(wèn) http://127.0.0.1:9501/ (示例請(qǐng)求地址) 即可看到運(yùn)行結(jié)果: your template is index.tpl and data is {"user":"easyswoole","time":1613659221},然后訪問(wèn) 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ù),訪問(wèn) http://127.0.0.1:9501,即可看到運(yùn)行結(jié)果:Welcome To Use EasySwoole ^_^!

支持常用的模板引擎

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

smarty/smarty

Smarty 是一個(gè)使用 PHP 寫(xiě)出來(lái)的模板引擎,是目前業(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 模板引擎的使用示例,其他模板引擎的使用方法大致類(lèi)似。

常見(jiàn)問(wèn)題

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

  • 報(bào)錯(cuò)結(jié)果類(lèi)似如下:
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ù)器沒(méi)有權(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());
    }
}
亚洲精品成人_精品成人一区_999视频在线播放_免费黄色在线_亚洲成人久久久_久久www免费视频
  • <kbd id="eqi2k"><code id="eqi2k"></code></kbd><cite id="eqi2k"><tbody id="eqi2k"></tbody></cite>
    一区精品视频| 国产一区二区免费在线观看| 亚欧精品在线| 亚洲国产欧美不卡在线观看| 欧美高清视频一区二区三区在线观看| 欧美日韩综合另类| 激情婷婷欧美| 444亚洲人体| 日本一区视频在线观看| 欧美精品一区二区视频| 国产乱人伦精品一区二区| 97视频中文字幕| 亚洲v日韩v欧美v综合| 亚洲国产网站| 国产精品18毛片一区二区| 性欧美videosex高清少妇| 一区二区国产在线观看| 国产一区免费在线| 欧美性天天影院| 国产精品久久一区二区三区| 日韩欧美激情一区二区| 国产精品国产三级欧美二区| 99c视频在线| 欧美日韩一区二区三区免费| 岛国视频一区| 国产一区激情| 蜜桃传媒一区二区| 国产一区二区高清| 欧美日韩精品不卡| 国产精品一二| 女同性一区二区三区人了人一 | 亚洲性人人天天夜夜摸| 99re热精品| 狠狠色噜噜狠狠狠狠色吗综合| 国产精品毛片va一区二区三区| 欧美久久久久久| 国产专区一区二区三区| 亚洲精品一品区二品区三品区| 久久久国产精品一区二区三区| 国产精品久久久久久模特| 三区精品视频观看| 国产精品成人观看视频免费| 伊甸园精品99久久久久久| 鲁鲁狠狠狠7777一区二区| 男女av一区三区二区色多| 欧美日韩亚洲一区三区| 欧美一区二区福利| 成人欧美一区二区三区在线观看 | 欧美日韩国产不卡在线看| 国产精品免费一区二区三区观看| 国精品一区二区| 亚洲精品第一区二区三区| 含羞草久久爱69一区| 午夜亚洲伦理| 国产精品久久久久久久免费软件| 欧美aⅴ99久久黑人专区| 麻豆一区区三区四区产品精品蜜桃| 久久电影一区| 免费中文字幕日韩欧美| 亚洲经典自拍| 亚洲国产精品123| 欧美午夜在线视频| 欧美日产一区二区三区在线观看| 日韩av电影免费在线| 欧美日韩在线高清| 欧美一区二区三区四区夜夜大片 | 欧美日本在线| 欧美三级小说| 亚洲午夜在线| av不卡免费看| 在线一区日本视频| 亚洲欧美卡通另类91av| 午夜亚洲激情| 97操在线视频| 国产精品二区二区三区| 国产伦理一区二区三区| 精品一区二区国产| 青青草成人网| 亚洲国产一区二区三区在线| 亚洲精品一区二| 国产精品swag| 国产九九精品| 国产日产精品一区二区三区四区| 国产精品夜夜夜一区二区三区尤| 狠狠色综合一区二区| 久久亚洲免费| 亚洲最大免费| 激情综合在线| 国产精品社区| 国产精品 日韩| 婷婷精品国产一区二区三区日韩| 欧美一区亚洲二区| 99精品欧美| 国产伦精品一区二区三| 日韩av一区二区三区在线| 在线视频精品一区| 国产日韩一区二区| 精品综合在线| 欧美色123| 国产精品一区二区a| 国产精品久久久久久久久久久久午夜片 | 国产欧美日韩亚洲| 国产精品视频免费一区二区三区 | 欧美另类一区| 欧美日韩国产一区精品一区| 一区二区三区免费看| 91精品国自产在线观看| 日韩精品福利视频| 亚洲美女一区| 精品乱码一区二区三区| 国产尤物精品| 国产精品免费区二区三区观看 | 91久久爱成人| 一区二区三区四区五区精品| 亚洲视频狠狠| 精品一区二区三区免费毛片| 这里只有精品66| 久久综合伊人77777麻豆| 日韩精品极品视频在线观看免费| 中国成人在线视频| 欧美资源一区| 国产精品视频福利| 亚洲精品8mav| 99热在线国产| 亚洲人体偷拍| 亚洲一区二区三区加勒比| 91成人免费视频| 国产综合久久| 日本一区二区三区视频在线观看| 91久久极品少妇xxxxⅹ软件| 欧美性天天影院| 国产精品乱看| 最新国产精品久久| 国产专区一区二区| 免费久久99精品国产自| 中国一区二区三区| 精品产品国产在线不卡| 一区二区av| 黑丝一区二区三区| 一区二区三区四区欧美日韩| 国产尤物91| 久久综合久久综合这里只有精品| 欧美天堂亚洲电影院在线观看 | 成人激情av| 亚洲资源av| 国模一区二区三区| 午夜精品一区二区三区四区| 97人人模人人爽人人少妇| 亚洲伦理精品| 午夜精彩国产免费不卡不顿大片| 欧美高清视频一区| 久久久久网址| 国产欧美欧洲| 国产高清自拍一区| 久久五月天婷婷| 亚洲欧洲在线一区| 黄色国产精品| 国内自拍一区| 欧美视频不卡| 激情国产一区| 亚洲国产片色| av成人免费观看| 91久久视频| 亚洲麻豆一区| 亚洲一区精彩视频| 麻豆精品网站| 91偷拍精品一区二区三区| 另类av一区二区| 免费在线观看成人av| 午夜综合激情| 欧美亚洲一区| 国产精品区二区三区日本| 国产精品免费在线 | 日本午夜一区二区三区| 久久免费99精品久久久久久| 国产综合色一区二区三区| 精品中文字幕人| 精品国产乱码久久久久久郑州公司| 国产精品一区二区你懂得| 国产亚洲福利社区| 日本精品视频一区| 在线电影看在线一区二区三区| 中文字幕一区综合| 欧美特黄a级高清免费大片a级| 欧美日韩一区二区三区在线视频| 精品1区2区3区4区| 国产一区二区三区免费不卡| 久久aⅴ乱码一区二区三区| 久久精品女人| 久草精品电影| 欧美喷水视频| 亚洲一区二区三区午夜| 99视频免费观看| 日本10禁啪啪无遮挡免费一区二区| 亚洲午夜在线观看| 亚洲日本成人| 精品久久久久久一区| 女人天堂亚洲aⅴ在线观看| 国产美女精品| 欧美精品国产精品久久久 |