自研 PHP 框架 1.1_模板引擎

城裡的野山參發表於2019-12-24

模板引擎

這一說明文件,主要用來說明如何從0開始引入第三方庫,並在自己的專案中正常使用。

1.1 版本中,我使用的 smarty 模板引擎,並沒有什麼特別的理由(就像 1.0 文件中所說,很多設計只是開發的靈光一閃,並沒有那麼多的為什麼)

決策流程

當確定了自己需要模板引擎之後,我是如何查詢資訊並作出決策,最重要的問題是,實踐操作是如何做的。

我看過很多的書籍、文件和部落格,其中很多作者給我的感覺很像高中時聽數學老師講課。

順著老師的思路走你覺得這個問題很簡單,但是當自己來做的時候,你會發現很多的細節問題,完全無從下手。

其中的原因在於,老師在講解時,很多分叉口(比如,某個問題需要套用哪個公式)並沒有給你指出來,因為在他看來這是如此簡單,簡單到是一個不需要思考的問題,所以很多細節直接被跳過。當我們自己接手的時候,每一個分叉口都是一個巨大的難題,往往會不知所措,實踐的難度比期望值大太多,結果就是失敗或者放棄。

所以,我希望提供更詳盡的資訊(日誌級別的思考記錄),不僅僅只是流程,還會摻雜大量的思考,大量的操作細節。

下面列舉的是我的解決步驟:

  1. Google,PHP template engine
    會看到一篇 Top7 的文章,點進去,瀏覽了一遍,隨便選了一個排第二的 smarty

  2. Packagist.org 查詢 smarty
    packagist.org 搜尋 samrty 就會找到相關資訊,按照說明安裝即可(按照說明安裝,這樣說法就是省略細節的說明,很像老師說的 就用這個公式就可以了)。
    這裡可能存在兩個問題:

    • 1.全英文,看不懂。

      chrome瀏覽器支援翻譯,這算是個解決辦法。終極辦法,還是要開始學英語,這是必經之路,如果想變得更好的話。

    • 2.composer是啥

      簡單的說,叫包管理工具,關鍵字都告訴你了,使用搜尋引擎吧。
      這裡吐槽下很多人的資訊查詢能力,最最最最最顯著的一點,有問題不知道先百度一下麼?!
      雖然,百度可能百度不出來你想要的東西,但是解決問題的步驟應該是這麼一個步驟,最起碼自己先查一下,找不到再問吧。百度的正確用法,或者說搜尋引擎的正確用法的前提是,你要知道關鍵詞,直白點說你要知道你要找的是什麼東西,關鍵詞有了,答案距你也就不遠了(後續涉及到額外知識的部分,會提供關鍵詞)。

  3. 在IDE中的專案根目錄下開啟終端,使用 composer 命令安裝
    可能存在如下幾個問題:

    • 什麼是IDE?
    • 專案根目錄下開啟終端怎麼搞?

      根據你使用的IDE不同,也有不同的方式,終極方法直接命令列到專案根目錄,windows下就是cmd。

    • composer命令安裝如何使用?

      使用 composer require xxxx,這樣使用的前提條件是:1.有安裝 composer;2.PATH路徑中包含了 composer

  4. 如何使用安裝的第三方庫
    使用 composer 安裝完成之後,會在根目錄下建立一個 vendor 資料夾,所有通過 composer 安裝的第三庫都會統一放置在這裡。

這裡複習一下 1.0 版本中曾經提及過的,每一次請求最終 PHP 引擎其實只執行了一個檔案 index.php,框架的作用只是將一個超級大檔案,分解成了各個部分,最終還是要組裝在一起,對外就是單個檔案 index.php

一個類或者方法如果要被使用,先得被定義。

也就是說,第三庫如果要使用,我們就必須在使用之前載入到 index.php 中(使用 include 或者 require),這裡有一個位置問題,1.1 版本中放置在這裡:

<?php
...
// 載入第三方庫檔案
include(VENDOR.'autoload.php');

$class_name = $obj->get('controller');
$func = $obj->get('func');

$namesapce = 'app.dmin.ontroller.'.$class_name;
//這裡是我們業務邏輯,也就是 APP 資料夾下的檔案
$app = new $namesapce;
$app->$func();

很顯然,第三方庫檔案如果放到業務邏輯之後肯定行不通。

而且,這裡的載入方式也顯得很簡單 inlcude(VENDOR.'autoload.php') ,簡單的一行就解決了第三方庫的載入問題,按照我們之前的方式,每一個檔案都要 includerequire,這裡很自然會有一個問題:

為什麼到這裡只要載入一個檔案就可以?

是因為只有一個檔案嗎?很顯然不是,單 smarty 一個庫就有幾十上百個檔案,更別說其他的依賴庫了,這裡如何解決的呢?

這裡引入一個知識點,自動載入。完成了前面的載入步驟,接下來我們就需要進行實際使用

以前沒用過 smarty 模板引擎,該怎麼辦?

最有效的方法不是百度,而是去看官方文件,官方文件都會有指導手冊,指導你如何使用,當然了,又是全英文。

比如說 smarty 模板引擎如何使用,可以看這裡 smarty引擎官方使用手冊,知道了模板要如何寫,我們繼續往下。

在方法中如何使用?

<?php
/**
 * 使用 smarty 模板引擎
 */
public function html_smarty()
{
    $smarty = new .marty();
    return $smarty->display(VIEW.'index/html_smarty.tpl');
}

上述的示例只是一個簡單的 demo,只是用來跑通業務,不需要複雜的邏輯。(這裡說一下,當學習一個新東西時,弄懂流程和原理最重要,不需要太多、太複雜的邏輯,邏輯說到底只是對工具的組合使用)

下面詳細介紹,我是如何知道要這麼寫,以及為什麼要這麼寫。

我是如何知道要怎麼寫的

因為我是第一次使用,根本就不知道要建立一個什麼名字(也就是這裡的 smarty)的物件,有人可能連要建立物件都不知道,更別說要使用 display 方法來生成 html 檔案了。

那我是如何知道的呢?

如果你是用 IDE 閱讀(推薦這樣閱讀)的,順著這個路徑 vendor/smarty/smarty/demo/index.php 開啟這個檔案,你就知道要怎麼寫了(畢竟別人都給了你示例,照著寫總歸是可以的)。

如果沒有 demo 檔案可供你參考,README.md 就必須要看了,可以從中找到如何使用或者教你如何使用的教程。

下面要說明的是為什麼寫成 new .marty(),而不是 new Smarty()。這個需要結合名稱空間來看。

首先,smarty 庫中的檔案本身是沒有使用名稱空間的,這就意味著其被載入到 index.php 之後,就相當於我們在根域中定義的類,加之 html.php 我們使用了名稱空間 app.dmin.ontroller,這導致 html.php 檔案本身在 app.dmin.ontroller 這個域中(參看名稱空間,裡面有詳細說明),如果使用 new Smarty(),系統會自動給其加上字首,實際使用時就變成了這樣 new app.dmin.ontroller.marty(),前面我們說過,smarty 庫檔案其實被載入到了根域下,這樣就找不到指定的檔案。

這裡因為 smarty 庫本身沒有使用名稱空間,如果使用名稱空間那又該如何使用呢?

回到根目錄下 index.php 的載入過程,如果第三方庫使用了名稱空間,載入之後的第三庫檔案並不在根域中,而是在第三方庫使用的名稱空間的指定域(假設為 namespace smarty; ,方便演示說明)中。

那麼在控制器檔案中使用時有下面兩種寫法

<?php
...
//不使用 use
public function html_smarty()
{
    $smarty = new smarty.marty();
    ...
}

<?php
...
//使用use
use smarty.marty;
public function html_smarty()
{
    $smarty = new Smarty();
    ...
}

請仔細比較兩者之間的區別,如果沒有使用 use 那麼就需要給解析引擎指明完整的路徑,也就是 smarty.marty(),如果使用了 use,在解析引擎的眼中,new Smarty()new smarty.marty() 是等價的,也就是前面不使用 use 所展示出來的樣子,這樣比較之後,可以很明顯的看出,use 其實起到的就是一個簡化的作用,推而廣之,任何支援別名的語言,別名所起到的作用也是為了簡化,為了使用更方便,無需過度關注如何實現這種細節。

PS:本系列文章最佳閱讀方式,IDE + 本地執行環境,IDE 中閱讀可配合 demo 執行增進理解,GitHub 地址

城裡的野山參

相關文章