Laravel Blade如何在幕后工作?

时间:2017-06-16 21:14:08

标签: php laravel blade

我试图找到解释这个的地方,但我找不到任何东西。

我非常喜欢刀片的一个特定方面,那就是php echo标签{{}}。我很好奇我怎么能在后端重复这个过程。

我试过的一个想法

我的一个想法是基本上像laravel一样制作一条路线,如下图所示。

处理程序:

Custom::Include('folder/index.custom.php');

index.custom.php:

<custom>paragraph here</custom>

网络浏览器:

<div id="custom">paragraph here</custom>

这个想法是我的处理程序将被放置在索引页面中。当它被调用时,它将执行file_get_contents,解析每一行寻找自定义标签,然后使用php echo打印输出。

这确实有用,然而,问题是当我到php时它不能工作,因为它是服务器端并且已经通过它一次。

这种方式似乎也过分走上正轨。我在这里添加了我的想法只是为了说明我是如何尝试复制该过程的。

有没有人对如何做到这一点有简单的解释?

2 个答案:

答案 0 :(得分:1)

您可以与 file_get_contentseval 一起玩转输出缓冲区

我的虚拟班级:

<?php

class Something
{

    public function getMatches($pattern, $string){
        preg_match_all($pattern, $string, $matches);        

        if(empty($matches[1]))
            return [];

        return $matches[1];
    }

    public function include($file){
        $contents = file_get_contents( $file);
        $contents = $this->execCodes($contents);

        echo $contents;
    }

    public function execCodes($contents){
        
        //match all @php code() @endphp
        $matches = $this->getMatches('/\@php(.*?)\@endphp/is', $contents);

        if(empty($matches))
            return $contents;

        $matches = array_unique($matches);

        foreach ($matches as $value) {
            
            //trim spaces
            $code = trim($value);

            $evaluatedCode = $this->getEvaluatedCode( $code ); //get output of evaluated code

            $code = $this->escapeRegExMetaChars($code);

            $pattern = "/(\@php.*?" . $code . '.*?\@endphp)/is'; //regex pattern for matching @php func() @endphp

            $contents = preg_replace($pattern, $evaluatedCode, $contents);  //replace all @php func() @endphp with evaluatedCode output

        }

        return $contents;

    }

    function escapeRegExMetaChars($string){

        $meta_chars = [ '\\', '^', '$', '.', '[', ']', '|', '(', ')', '?', '*', '+', '{', '}', '-', '\'', '/'];

        $len = strlen($string);
        $new_string = '';

        for($x = 0; $x < $len; $x++){

            if( in_array($string[$x], $meta_chars) ){
                $new_string .= '\\' . $string[$x];
            }else{
                $new_string .= $string[$x];
            }

        }
        
        return $new_string;

    }

    public function getEvaluatedCode(string $code){

        if(preg_match('/^(die|exit)/i', $code)){
            return "$code not allowed here";
        }

        //disable output buffers then return the ouput of the eval'ed code
        ob_start();
        eval($code);
        $output = ob_get_contents();
        ob_end_clean();

        return $output;

    }


}

?>

test.html就像

<div>
    @php
        echo "Something";
    @endphp
</div>
<strong>
    This is a test
</strong>

那么:

$some = new Something();
$some->include('test.html');

输出应该是这样的:

Something
This is a test 

您可以对 @if @endif@foreach @endforeach{{ }} 等执行相同操作 你只需要做更多的编码

答案 1 :(得分:0)

我认为您正在寻找自定义刀片指令。

以下示例创建一个@datetime($var)指令,该指令格式化给定的$var,该指针应该是DateTime的实例:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        Blade::directive('datetime', function ($expression) {
            return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
        });
    }

    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}