自歷來到新公司就一直很忙,最近這段時間終於稍微閒了一點,趕忙接着寫這個系列,感受再不寫就爛尾了。php
以前咱們說到,拿到{{ $name }}
這樣一段內容時,咱們只須要將它轉化成<?php echo $name ?>
這樣,就能夠識別了,輸出相應的變量值。html
那就要須要正則匹配{{ $name }}
,而後替換掉{{
和}}
,分別替換成<?php echo
和?>
。git
可是要想到一個問題,若是我在 view 裏寫了 php 的代碼,其中含有{{ $name }}
,也會被替換。例子以下:github
<?php $name = 'test'; $str = "{{ $name }}"; ?>
要解決這個問題,咱們須要將 PHP 的代碼去掉,只留下 html 代碼再作替換的處理。幸虧 PHP 有一個方法 token_get_all,會將提供的內容按 PHP 標記進行分割。使用此方法解析以下內容:ui
$content = <<<VIEW <?php \$name = 'test'; \$str = "{{ \$name }}"; ?> <html> <body>{{ \$name }}</body> <html> VIEW; print_r(token_get_all($content));
這裏$
符號前加\
是爲了轉移,在真正是現實不須要。結果以下:this
Array ( [0] => Array ( [0] => 379 [1] => <?php [2] => 1 ) [1] => Array ( [0] => 382 [1] => [2] => 2 ) [2] => = [3] => Array ( [0] => 382 [1] => [2] => 2 ) [4] => Array ( [0] => 323 [1] => 'test' [2] => 2 ) [5] => ; [6] => Array ( [0] => 382 [1] => [2] => 2 ) [7] => = [8] => Array ( [0] => 382 [1] => [2] => 3 ) [9] => " [10] => Array ( [0] => 322 [1] => {{ [2] => 3 ) [11] => Array ( [0] => 320 [1] => $name [2] => 3 ) [12] => Array ( [0] => 322 [1] => }} [2] => 3 ) [13] => " [14] => ; [15] => Array ( [0] => 382 [1] => [2] => 3 ) [16] => Array ( [0] => 381 [1] => ?> [2] => 4 ) [17] => Array ( [0] => 321 [1] => <html> <body>{{ $name }}</body> <html> [2] => 5 ) )
能夠看到 PHP 相關的代碼被解析了,咱們只須要判斷出是 html 代碼,而後作替換就能夠了。其中的321就是定義好的常量T_INLINE_HTML
的值,標記解析出來的就是 html 代碼。code
咱們定義view文件的後綴爲sf,那咱們就能夠在controller/model/view
目錄下建立view.sf
文件,內容以下orm
<?php $title = 'It is a title'; $str = "{{ $title }}"; ?> <html> <head> <title>{{ $title }}</title> <head> <body> <h2>{{ $str }}</h2> <p>{{ $body }}<p> </body> </html>
而後咱們來改造Controller
中的render
方法,代碼以下htm
public function render($view, $params = []) { $file = '../views/' . $view . '.sf'; $fileContent = file_get_contents($file); $result = ''; foreach (token_get_all($fileContent) as $token) { if (is_array($token)) { list($id, $content) = $token; if ($id == T_INLINE_HTML) { $content = preg_replace('/{{(.*)}}/', '<?php echo $1 ?>', $content); } $result .= $content; } else { $result .= $token; } } $generatedFile = '../runtime/cache/' . md5($file); file_put_contents($generatedFile, $result); extract($params); require_once $generatedFile; }
修改actionView
以下blog
public function actionView() { $this->render('site/view', ['body' => 'Test body information']); }
訪問 http://localhost/simple-framework/public/index.php?r=site/view ,獲得以下頁面
今天就先到這裏。項目內容和博客內容也都會放到Github上,歡迎你們提建議。
code:https://github.com/CraryPrimitiveMan/simple-framework/tree/1.1
blog project:https://github.com/CraryPrimitiveMan/create-your-own-php-framework