目次
1. View 解析プロセス
2. Blade エンジン
3. 后话
ホームページ バックエンド開発 PHPチュートリアル Laravel テンプレート エンジン (Blade) の原理の簡単な分析

Laravel テンプレート エンジン (Blade) の原理の簡単な分析

Jun 20, 2016 pm 12:45 PM

前回述べたように、テンプレートエンジンは一般的に次の 3 つのことを行います。

  • 変数値の出力 (エコー)

  • 条件判断ループ (if ... else、for、foreach、while)

  • 他のファイルの導入または継承

  • Laravel を見てみましょう。テンプレート エンジンはこれら 3 つのことを処理します。この記事はLaravel 5.1の実装をベースに書いています。

    1. View 解析プロセス

    Laravel の View 部分には、直接出力と Blade エンジンを使用した「コンパイル」後の出力という 2 つの組み込み出力システムがあります。デフォルトでは、これらはファイル名を介して出力されます。選択: .blade.php 接尾辞はテンプレート ビュー ファイルとみなされ、他の .php ファイルは PHP 自体に従って実行されます。 PHP コードは Blade テンプレート ファイルに自由に埋め込むことができますが、それを使用しない場合は、システムが構文解析や置換を実行する必要がないため、効率が向上します。

    View コンポーネントの出力を使用する場合、ヘルパーで提供される view 関数を呼び出すか、Facades が提供する静的インターフェイス View::make() を使用するかにかかわらず、IlluminateViewFactory の make メソッドが実際に実行されます。これをエントリ ポイントとして使用すると、ビューの解析出力のプロセスを簡単に知ることができます。

  • ビュー ファイルを見つけます。

  • からの応答を取得します。ファイル名のサフィックスに基づくコンテナ。エンジン

  • は、解析する必要があるデータをビュー ファイルに公開しながら、ビュー ファイルをロードするか、コンパイル後にコンパイルされたファイルをロードします。環境。

  • Factory の一部のメソッドは、上記の最初のステップを完了します。ファイル検索は、IlluminateFilesystemFilesystem のメソッドを使用します。このクラスには、イベントに関連するメソッドもいくつかあります。ここで言及されています。

    上記の手順で、取得したビュー ファイルを「コンパイル」する必要がある場合、エンジンは「ブレード コンパイラ」を呼び出して元のビューを「コンパイル」し、それをキャッシュ ディレクトリに保存してから、出力。次回呼び出し時にソースファイルが変更されていないことが判明した場合は、再コンパイルせずに直接キャッシュファイルを取得して出力します。

    CompilerEngine によって呼び出されるコンパイラは、CompilerInterface インターフェイスの実装です。デフォルトでは、これは BladeCompiler のみです (パーサーがどのように挿入されるかを知らない場合は、Laravel のサービス コンテナを理解する必要があります。詳細はこちら)。

    2. Blade エンジン

    この記事の次のステップは、Blade がどのように「コンパイル」されるかです。私は常に「コンパイル」という単語を引用符で囲みます。これは明らかに、本当の意味でのコードのコンパイルのプロセスではなく、単なる定期的な置換のプロセスだからです。

    Laravel のテンプレート エンジンは非常にシンプルであることがわかりますが、基本的に次の 2 つの点を理解するだけで済みます。 {{ と }} の間には、出力されるコンテンツが含まれます。5.0 以降のバージョンでは、それぞれエスケープ出力用とエスケープなし出力用の 2 つの拡張メソッド {{{ ... }}} と {!! .. !!} があります。 { { ... }} も、デフォルトではどこでもエスケープされます。

  • @ シンボルは、PHP 独自の if else foreach や拡張インクルードの yield stop などを含めて、命令で始まります。
  • Blade は実際に次の 4 つの状況で解析を処理します。

  • 拡張機能

  • ステートメント ブロック (コマンドの開始) @付き)

  • コメント -> コメント ({{-- ... --}} メソッドの記述、解析後は HTML コメントではなく PHP コメントになります)

  • Echos -> 出力

  • 解析 (解析はキャッシュに存在しません) プロセス中、Blade は最初に token_get_all 関数を使用して、ビュー ファイルの一部を取得します。は、PHP インタープリターによって HTML (T_INLINE_HTML) と見なされ、上記の 4 つの状況を順番に解析します。

    拡張部分は、ユーザー定義のコンパイラを呼び出して文字列を解析します。拡張性を追加するために、BladeCompiler には extend メソッドが提供されています。
  • コメント部分も非常に簡単で、{{-- ... --}} を に置き換えるだけです。

    出力セクションには、上記の 3 つの状況に対応する 3 つのメソッドが用意されています。

    compileRawEchos -> エスケープされていないコンテンツを出力します ({!! . .. !!})

  • compileEscapedEchos -> エスケープされた内容を出力します ({{{ ... }}})

  • compile RegularEchos -> 通常の出力 ({{ ... }})

  • デフォルトでは、文字置換後、compileEscapedEchos と COMPILEREGULAREchos の関数本体は、どちらも出力時、実際にはまったく同じです。 e() の補助関数を呼び出して出力します。 🎜>

    これは 5.0 以降のバージョンで変更されたようです。以前のバージョンでは、compile RegularEchos は、compileRawEchos の動作を実行していました。ただし、この 2 つの関数にはまだ 1 つの違いがあります。compile RegularEchos のエスケープ関数は setEchoFormat (ただし、デフォルトは e()) を通じてカスタマイズできますが、compileEscapedEchos ではカスタマイズができません。
  • エコーの後の内容も正規表現に置き換えられています:

    <?php    public function compileEchoDefaults($value)    {        return preg_replace('/^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/s', 'isset($1) ? $1 : $2', $value);    }
    ログイン後にコピー

    从正则表达式中可以看出来输出提供了一个 or 的关键字,$a or $b 的写法会被替换成 isset($a) ? $a : $b。

    语句块部分可以分成三种情况:

  • 和 PHP 本身一样的 if else foreach 以及扩展的 unless 等流程和循环控制的关键字;

  • include yield 等模板文件引入、内容替换的部分;

  • lang choice can 等涉及到 Laravel 其他组件的功能性关键字。

  • 第一种情况是很简单的替换过程,本身 PHP 为了在 HMTL 和 PHP 混合书写方便就提供了 if foreach 等几个关键字使用冒号和 endif 等关键字代替大括号来控制流程的方法。

    第二种情况稍微复杂一点,比如下面的函数:

    <?php    protected function compileYield($expression)    {        return "<?php echo \$__env->yieldContent{$expression}; ?>";    }
    ログイン後にコピー

    解析之后的语句是调用了一个名为 $_env 的实例中的方法。这个实例其实就是 Illuminate\View\Factory 的实例:

    Factory 的构造函数:

    <?php    public function __construct(EngineResolver $engines, ViewFinderInterface $finder, Dispatcher $events)    {        ...        $this->share('__env', $this);    }
    ログイン後にコピー

    Illuminate\View\View 中:

    <?php    protected function getContents()    {        return $this->engine->get($this->path, $this->gatherData());    }    /**     * Get the data bound to the view instance.     *     * @return array     */    protected function gatherData()    {        $data = array_merge($this->factory->getShared(), $this->data);        ...        return $data;    }
    ログイン後にコピー

    由此也可以看出 each yield 等指令的实现也是在 Factory 中,分别对应的是 renderEach yieldContent 等。

    所以文件引入等指令的实现方式就是:在主视图输出的时候,通过注入的 $__env 来重复调用 Factory 中的 make 方法来输出引入的文件。

    至于 lang 等关键字,替换后就是使用 app() 函数来调用 Laravel 的其他组件。此外 Blade 还提供了 inject 关键字来调用任何你想使用的组件。

    除了以上这些,你还可以通过 directive 方法来增加一些自定义指令。

    compileStatements 方法中最后进行正则替换的正则表达式看起来比较复杂:

    /\B@(\w+)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x
    ログイン後にコピー

    这是因为正则后面的一部分实现了递归模式来匹配语句块中括号的数量。

    3. 后话

    通过以上的分析可以看出来 Laravel 的视图组件还是十分简洁的,同时也不失灵活性和可扩展性。如果有兴趣的话,也可以实现一个自己的模板解析引擎。

    如果你想在其他项目中使用 Blade 引擎,通过 Composer 安装下来之后会发现还有 Container、Events 等部分,这和 Laravel 本身有关。

    为了能够在任何地方使用 Blade,我把它核心的部分提取了出来,去掉了其他组件的依赖,也不再依赖文件扩展名来选择引擎:

    项目地址:https://github.com/XiaoLer/blade

    此外也通过这个提取之后的版本做了一个 yii2 能够使用的版本:https://github.com/XiaoLer/yii2-blade。在之前尝试的版本中直接使用 Laravel 的 View 组件并不灵活,现在感觉好多了。

    个人博客原文:http://0x1.im/blog/laravel/laravel-blade-engine.html

    このウェブサイトの声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

    ホットAIツール

    Undresser.AI Undress

    Undresser.AI Undress

    リアルなヌード写真を作成する AI 搭載アプリ

    AI Clothes Remover

    AI Clothes Remover

    写真から衣服を削除するオンライン AI ツール。

    Undress AI Tool

    Undress AI Tool

    脱衣画像を無料で

    Clothoff.io

    Clothoff.io

    AI衣類リムーバー

    AI Hentai Generator

    AI Hentai Generator

    AIヘンタイを無料で生成します。

    ホットツール

    メモ帳++7.3.1

    メモ帳++7.3.1

    使いやすく無料のコードエディター

    SublimeText3 中国語版

    SublimeText3 中国語版

    中国語版、とても使いやすい

    ゼンドスタジオ 13.0.1

    ゼンドスタジオ 13.0.1

    強力な PHP 統合開発環境

    ドリームウィーバー CS6

    ドリームウィーバー CS6

    ビジュアル Web 開発ツール

    SublimeText3 Mac版

    SublimeText3 Mac版

    神レベルのコード編集ソフト(SublimeText3)

    Laravelでフラッシュセッションデータを使用します Laravelでフラッシュセッションデータを使用します Mar 12, 2025 pm 05:08 PM

    Laravelは、直感的なフラッシュメソッドを使用して、一時的なセッションデータの処理を簡素化します。これは、アプリケーション内に簡単なメッセージ、アラート、または通知を表示するのに最適です。 データは、デフォルトで次の要求のためにのみ持続します。 $リクエスト -

    PHPのカール:REST APIでPHPカール拡張機能を使用する方法 PHPのカール:REST APIでPHPカール拡張機能を使用する方法 Mar 14, 2025 am 11:42 AM

    PHPクライアントURL(CURL)拡張機能は、開発者にとって強力なツールであり、リモートサーバーやREST APIとのシームレスな対話を可能にします。尊敬されるマルチプロトコルファイル転送ライブラリであるLibcurlを活用することにより、PHP Curlは効率的なexecuを促進します

    Laravelテストでの簡略化されたHTTP応答のモッキング Laravelテストでの簡略化されたHTTP応答のモッキング Mar 12, 2025 pm 05:09 PM

    Laravelは簡潔なHTTP応答シミュレーション構文を提供し、HTTP相互作用テストを簡素化します。このアプローチは、テストシミュレーションをより直感的にしながら、コード冗長性を大幅に削減します。 基本的な実装は、さまざまな応答タイプのショートカットを提供します。 Illuminate \ support \ facades \ httpを使用します。 http :: fake([[ 'google.com' => 'hello world'、 'github.com' => ['foo' => 'bar']、 'forge.laravel.com' =>

    PHPロギング:PHPログ分析のベストプラクティス PHPロギング:PHPログ分析のベストプラクティス Mar 10, 2025 pm 02:32 PM

    PHPロギングは、Webアプリケーションの監視とデバッグ、および重要なイベント、エラー、ランタイムの動作をキャプチャするために不可欠です。システムのパフォーマンスに関する貴重な洞察を提供し、問題の特定に役立ち、より速いトラブルシューティングをサポートします

    Codecanyonで12の最高のPHPチャットスクリプト Codecanyonで12の最高のPHPチャットスクリプト Mar 13, 2025 pm 12:08 PM

    顧客の最も差し迫った問題にリアルタイムでインスタントソリューションを提供したいですか? ライブチャットを使用すると、顧客とのリアルタイムな会話を行い、すぐに問題を解決できます。それはあなたがあなたのカスタムにより速いサービスを提供することを可能にします

    PHPにおける後期静的結合の概念を説明します。 PHPにおける後期静的結合の概念を説明します。 Mar 21, 2025 pm 01:33 PM

    記事では、PHP 5.3で導入されたPHPの後期静的結合(LSB)について説明し、より柔軟な継承を求める静的メソッドコールのランタイム解像度を可能にします。 LSBの実用的なアプリケーションと潜在的なパフォーマ

    フレームワークのカスタマイズ/拡張:カスタム機能を追加する方法。 フレームワークのカスタマイズ/拡張:カスタム機能を追加する方法。 Mar 28, 2025 pm 05:12 PM

    この記事では、フレームワークにカスタム機能を追加し、アーキテクチャの理解、拡張ポイントの識別、統合とデバッグのベストプラクティスに焦点を当てています。

    See all articles