hyperf 十三 视图

教程:Hyperf

composer地址:hyperf/view - Packagist

本次测试使用twig

twig composedr地址:twig/twig - Packagist

twig 文档地址:Home - Twig - The flexible, fast, and secure PHP template engine

一、安装

composer require hyperf/view:v2.2.33
composer require twig/twig

二、配置

创建config/autoload/view.php文件。

php bin/hyperf.php vendor:publish hyperf/view

#/config/autoload/view.php
use Hyperf\View\Engine\TwigEngine;
//或者 use App\Engine\TwigEngine;
use Hyperf\View\Mode;
return [
    'engine' => TwigEngine::class,//视图渲染引擎
    'mode' => Mode::TASK,//视图渲染模式
    'config' => [
        'view_path' => BASE_PATH . '/storage/view/',//视图文件默认地址
        'cache_path' => BASE_PATH . '/runtime/view/',//视图文件缓存地址
    ],
];

 若task没引入,则引入task。

composer require hyperf/task

Task 模式下,视图渲染工作是在 Task Worker 进程中完成的。task进程和worker进程内存不互通,所以调用 render 时传递数据到视图进行数据的渲染。

若使用 Sync 模式渲染视图时,请确保相关引擎是协程安全的,否则会出现数据混淆的问题,建议使用更加数据安全的 Task 模式。

配置静态资源。

#/config/autoload/server.php
'settings' => [
        ……
        // Task Worker 数量,根据您的服务器配置而配置适当的数量
        'task_worker_num' => 2,
        // 因为 `Task` 主要处理无法协程化的方法,所以这里推荐设为 `false`,避免协程下出现数据混淆的情况
        'task_enable_coroutine' => false,
    ],

三、实现

#namespace App\Engine\TwigEngine 

use Hyperf\View\Engine\EngineInterface;
use Hyperf\View\Engine\TwigEngine as EngineTwigEngine;

class TwigEngine implements EngineInterface
{
    public function render($template, $data, $config): string
    {
        $engine = new EngineTwigEngine();
        return $engine->render($template, $data, $config);
    }
}


#App\Controller\TestController
public function test6(RenderInterface $render)
    {
        return $render->render('test.html', ['name' => 'Hyperf']);
    }

#/strage/view/test.html
hello {{name}}

四、实现原理

实现原理也不难理解。根据hyperf/view模块,由配置文件设定RenderInterface实现类Render,调用Render::render()时,调用Render::getContents()。getContents中根据构造中由config/autoload/view.php设定的engine类设置engine值,并调用对应的render()方法。

#Hyperf\View\ConfigProvider
public function __invoke(): array
    {
        return [
            'dependencies' => [
                RenderInterface::class => Render::class,
            ],
        ……
        ];
    }

#Hyperf\View\Render
public function __construct(ContainerInterface $container, ConfigInterface $config)
    {
        $engine = $config->get('view.engine', NoneEngine::class);
        if (! $container->has($engine)) {
            throw new EngineNotFindException("{$engine} engine is not found.");
        }

        $this->engine = $engine;
        $this->mode = $config->get('view.mode', Mode::TASK);
        $this->config = $config->get('view.config', []);
        $this->container = $container;
    }

    public function render(string $template, array $data = []): ResponseInterface
    {
        return $this->response()
            ->withAddedHeader('content-type', $this->getContentType())
            ->withBody(new SwooleStream($this->getContents($template, $data)));
    }

    public function getContents(string $template, array $data = []): string
    {
        try {
            switch ($this->mode) {
                case Mode::SYNC:
                    /** @var EngineInterface $engine */
                    $engine = $this->container->get($this->engine);
                    $result = $engine->render($template, $data, $this->config);
                    break;
                case Mode::TASK:
                default:
                    $executor = $this->container->get(TaskExecutor::class);
                    $result = $executor->execute(new Task([$this->engine, 'render'], [$template, $data, $this->config]));
                    break;
            }

            return $result;
        } catch (\Throwable $throwable) {
            throw new RenderException($throwable->getMessage(), $throwable->getCode(), $throwable);
        }
    }


#Hyperf\View\Engine\TwigEngine 
use Twig\Environment;
use Twig\Loader\FilesystemLoader;

class TwigEngine implements EngineInterface
{
    public function render($template, $data, $config): string
    {
        $loader = new FilesystemLoader($config['view_path']);
        $twig = new Environment($loader, ['cache' => $config['cache_path']]);

        return $twig->render($template, $data);
    }
}    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lsswear

感谢大佬打赏 q(≧▽≦q)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值