
最佳答案
讨论数量:
<?php
/**
* Created by PhpStorm.
* User: leo108
* Date: 2018/4/22
* Time: 15:15
*/
namespace App;
use Exception;
use Illuminate\View\Compilers\BladeCompiler;
use Illuminate\View\Engines\PhpEngine;
use Throwable;
class StringCompilerEngine extends PhpEngine
{
/**
* @var BladeCompiler
*/
protected $compiler;
/**
* StringCompilerEngine constructor.
* @param BladeCompiler $compiler
*/
public function __construct(BladeCompiler $compiler)
{
$this->compiler = $compiler;
}
public function renderString($__tpl, $__data = [])
{
$__compiled = $this->compiler->compileString($__tpl);
$obLevel = ob_get_level();
ob_start();
extract($__data, EXTR_SKIP);
try {
eval('?> '.$__compiled);
} catch (Exception $e) {
$this->handleViewException($e, $obLevel);
} catch (Throwable $e) {
$this->handleViewException(new FatalThrowableError($e), $obLevel);
}
return ltrim(ob_get_clean());
}
}
<?php
/**
* Created by PhpStorm.
* User: leo108
* Date: 2018/4/22
* Time: 15:15
*/
namespace App;
use Exception;
use Illuminate\View\Compilers\BladeCompiler;
use Illuminate\View\Engines\PhpEngine;
use Throwable;
class StringCompilerEngine extends PhpEngine
{
/**
* @var BladeCompiler
*/
protected $compiler;
/**
* StringCompilerEngine constructor.
* @param BladeCompiler $compiler
*/
public function __construct(BladeCompiler $compiler)
{
$this->compiler = $compiler;
}
public function renderString($__tpl, $__data = [])
{
$__compiled = $this->compiler->compileString($__tpl);
$obLevel = ob_get_level();
ob_start();
extract($__data, EXTR_SKIP);
try {
eval('?> '.$__compiled);
} catch (Exception $e) {
$this->handleViewException($e, $obLevel);
} catch (Throwable $e) {
$this->handleViewException(new FatalThrowableError($e), $obLevel);
}
return ltrim(ob_get_clean());
}
}
@leo 试了一下,是可以的,但是如果用到了blade 里的@if @foreach 模板里就会渲染到$__env 运行后,由于$__env 没有定义所以报错了。想问一下这个应该怎么处理。
经过查看源码得知,视图在实例化 Illuminate\View\Factory 类时,已经给变量$__env 传值了.所以问题也就解决了.
Illuminate\View\Factory
/** * Create a new view factory instance. * * @param \Illuminate\View\Engines\EngineResolver $engines * @param \Illuminate\View\ViewFinderInterface $finder * @param \Illuminate\Contracts\Events\Dispatcher $events * @return void */ public function __construct(EngineResolver $engines, ViewFinderInterface $finder, Dispatcher $events) { $this->finder = $finder; $this->events = $events; $this->engines = $engines; $this->share('__env', $this); }
在你这个类里应该添加上这个实例就可以了
public function renderString($__tpl, $__data = []) { // view() 可以用其它 只是简要说明一下这个解决的方法 $__data = array_merge(['__env'=>view()],$__data); $__compiled = $this->compiler->compileString($__tpl); $obLevel = ob_get_level(); ob_start(); extract($__data, EXTR_SKIP); try { eval('?> '.$__compiled); } catch (Exception $e) { $this->handleViewException($e, $obLevel); } catch (Throwable $e) { $this->handleViewException(new FatalThrowableError($e), $obLevel); } return ltrim(ob_get_clean()); }