Laravel 5 - 在服务器上使用Blade API编译字符串和插值

8
使用Blade服务容器,我希望将一个包含标记的字符串进行编译,以便它可以添加到Blade模板中,并进一步插值。因此,我在服务器上从数据库检索到了一个邮件字符串(出于简洁考虑而缩短为abridge)。
<p>Welcome {{ $first_name }},</p>

我希望您可以被插值到某个位置。
<p>Welcome Joe,</p> 

我可以将其作为$content发送到Blade模板,然后让模板呈现所有内容和标记,因为Blade不会进行两次插值。目前,我们的模板是由客户端制作并存储在数据库中。

Blade::compileString(value)生成<p>欢迎 <?php echo e($first_name); ?>,</p>,但是我无法通过Blade API使$first_name解析为Joe,而且它也不会在Blade模板中进行解析,只会像这样在邮件中显示带有PHP分隔符的字符串:

<p>Welcome <?php echo e($first_name); ?>,</p>

有什么建议吗?
1个回答

15
这应该就可以了:
// CustomBladeCompiler.php

use Symfony\Component\Debug\Exception\FatalThrowableError;

class CustomBladeCompiler
{   
    public static function render($string, $data)
    {
        $php = Blade::compileString($string);

        $obLevel = ob_get_level();
        ob_start();
        extract($data, EXTR_SKIP);

        try {
            eval('?' . '>' . $php);
        } catch (Exception $e) {
            while (ob_get_level() > $obLevel) ob_end_clean();
            throw $e;
        } catch (Throwable $e) {
            while (ob_get_level() > $obLevel) ob_end_clean();
            throw new FatalThrowableError($e);
        }

        return ob_get_clean();
    }
}

使用方法:

$first_name = 'Joe';
$dbString = '<p>Welcome {{ $first_name }},</p>';

return CustomBladeCompiler::render($dbString, ['first_name' => $first_name]);

感谢 @tobiaLaracasts论坛 上的帮助。

我使用了临时的刀片模板而不是缓冲区,但这种方式更好。 - Paul Basenko
如果我使用@foreach,$php值包含以下内容:$__env->addLoop($__currentLoopData); foreach($__currentLoopData as $app): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ;...(其中$__env不可访问),有任何想法吗? - Simon Fakir
$path = resource_path('views/' . $id . '.blade.php'); file_put_contents($path,$needCompileString); - Qh0stM4N
如果我的dbString像<p>Welcome {{ $name }},那么我会得到类似于Undefined variable: name的错误。但是,我想要得到类似于<p>Welcome {{ $name }}的结果。有什么建议吗? - Pooja Jadav
这真的帮了我大忙!不知道现在还是不是这样做的? - Alex
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接