View Parser可以對視圖文件中包含的偽變量執(zhí)行簡單的文本替換。它可以解析簡單變量或變量標簽對。
偽變量名稱或控件構(gòu)造用大括號括起來,如下所示:
<html>
<head>
<title>{blog_title}</title>
</head>
<body>
<h3>{blog_heading}</h3>
{blog_entries}
<h5>{title}</h5>
<p>{body}</p>
{/blog_entries}
</body>
</html>
這些變量不是實際的PHP變量,而是純文本表示形式,使您可以從模板(查看文件)中消除PHP。
注解
CodeIgniter也不會要求你使用這個類,因為(使用例如在您的視圖頁面使用純PHP 視圖渲染器)讓他們跑快一點。但是,如果開發(fā)人員與認為使用PHP會感到有些困惑的設計師合作,則他們更喜歡使用某種形式的模板引擎。
加載解析器類的最簡單方法是通過其服務:
$parser = \Config\Services::parser();
或者,如果您不使用Parser
該類作為默認渲染器,則可以直接實例化它:
$parser = new \CodeIgniter\View\Parser();
然后,您可以使用它提供的三種標準渲染方法中的任何一種: render(viewpath,options,save),setVar(name,value,context)和 setData(data,context)。您還可以通過setDelimiters(left,right)方法直接指定定界符。
使用Parser
,您的視圖模板僅由解析器本身處理,而不像常規(guī)的視圖PHP腳本那樣處理。解析器將忽略此類腳本中的PHP代碼,并且僅執(zhí)行替換。
這是有目的的:查看沒有PHP的文件。
該Parser
級的流程“PHP / HTML腳本”存儲在應用程序的視圖路徑。這些腳本不能包含任何PHP。
每個視圖參數(shù)(我們稱為偽變量)都會根據(jù)您為其提供的值的類型觸發(fā)替換。偽變量不會提取到PHP變量中;相反,它們的值通過偽變量語法訪問,其中其名稱在花括號內(nèi)引用。
Parser類在內(nèi)部使用關聯(lián)數(shù)組,以累積偽變量設置,直到調(diào)用它為止render()
。這意味著您的偽變量名稱必須唯一,否則后面的參數(shù)設置將覆蓋以前的參數(shù)。
這還會影響腳本中不同上下文的轉(zhuǎn)義參數(shù)值。您將必須為每個轉(zhuǎn)義的值賦予唯一的參數(shù)名稱。
您可以使用該render()
方法來解析(或渲染)簡單的模板,如下所示:
$data = [
'blog_title' => 'My Blog Title',
'blog_heading' => 'My Blog Heading'
];
echo $parser->setData($data)
->render('blog_template');
視圖參數(shù)setData()
作為要在模板中替換的數(shù)據(jù)的關聯(lián)數(shù)組傳遞到。在上面的示例中,模板將包含兩個變量:{blog_title}和{blog_heading}第一個參數(shù)render()
包含視圖文件的名稱,其中blog_template是視圖文件的名稱。
重要
如果省略文件擴展名,則視圖應以.php擴展名結(jié)尾。
可以將幾個選項傳遞給render()
或renderString()
方法。
cache
-保存視圖結(jié)果的時間(以秒為單位);對renderString()忽略cache_name
-用于保存/檢索緩存的視圖結(jié)果的ID;默認為viewpath;對renderString()忽略
saveData
-如果應為隨后的調(diào)用保留視圖數(shù)據(jù)參數(shù),則為true。默認為false
cascadeData
-如果應將偽變量設置傳遞給嵌套,則為true替代; 默認為true
echo $parser->render('blog_template', [
'cache' => HOUR,
'cache_name' => 'something_unique',
]);
支持三種類型的替換:簡單,循環(huán)和嵌套。替換按照添加偽變量的相同順序執(zhí)行。
解析器執(zhí)行的簡單替換是偽變量的一對一替換,其中對應的數(shù)據(jù)參數(shù)具有標量或字符串值,如本例所示:
$template = '<head><title>{blog_title}</title></head>';
$data = ['blog_title' => 'My ramblings'];
echo $parser->setData($data)->renderString($template);
// Result: <head><title>My ramblings</title></head>
在Parser
用“可變對”,用于嵌套取代或循環(huán),并用一些先進的構(gòu)建體用于條件替代很多進一步需要替換。
解析器執(zhí)行時,通常
當偽變量的值是數(shù)組的順序數(shù)組(如行設置的數(shù)組)時,將發(fā)生循環(huán)替換。
上面的示例代碼允許替換簡單變量。如果您希望重復整個變量塊,而每次迭代都包含新值,該怎么辦?考慮一下我們在頁面頂部顯示的模板示例:
<html>
<head>
<title>{blog_title}</title>
</head>
<body>
<h3>{blog_heading}</h3>
{blog_entries}
<h5>{title}</h5>
<p>{body}</p>
{/blog_entries}
</body>
</html>
在上面的代碼中,您會注意到一對變量:{blog_entries} data…{/ blog_entries}。在這種情況下,這些對之間的整個數(shù)據(jù)塊將重復多次,這與參數(shù)數(shù)組的“ blog_entries”元素中的行數(shù)相對應。
解析變量對使用與上面顯示的相同的代碼來解析單個變量,但是,您將添加一個與變量對數(shù)據(jù)相對應的多維數(shù)組??紤]以下示例:
$data = [
'blog_title' => 'My Blog Title',
'blog_heading' => 'My Blog Heading',
'blog_entries' => [
['title' => 'Title 1', 'body' => 'Body 1'],
['title' => 'Title 2', 'body' => 'Body 2'],
['title' => 'Title 3', 'body' => 'Body 3'],
['title' => 'Title 4', 'body' => 'Body 4'],
['title' => 'Title 5', 'body' => 'Body 5']
]
];
echo $parser->setData($data)
->render('blog_template');
偽變量的值blog_entries
是關聯(lián)數(shù)組的順序數(shù)組。外層沒有與每個嵌套“行”關聯(lián)的鍵。
如果您的“對”數(shù)據(jù)來自數(shù)據(jù)庫結(jié)果(已經(jīng)是一個多維數(shù)組),則可以簡單地使用數(shù)據(jù)庫getResultArray()
方法:
$query = $db->query("SELECT * FROM blog");
$data = [
'blog_title' => 'My Blog Title',
'blog_heading' => 'My Blog Heading',
'blog_entries' => $query->getResultArray()
];
echo $parser->setData($data)
->render('blog_template');
如果您要循環(huán)的數(shù)組包含對象而不是數(shù)組,則解析器將首先asArray
在對象上查找方法。如果存在,則將調(diào)用該方法,然后如上所述將結(jié)果數(shù)組循環(huán)。如果不asArray
存在任何方法,則該對象將被強制轉(zhuǎn)換為數(shù)組,并且其公共屬性將對解析器可用。
這對于Entity類尤其有用,它具有一個asArray方法,該方法返回所有公共和受保護的屬性(減去_options屬性),并使它們對解析器可用。
當偽變量的值是值的關聯(lián)數(shù)組(例如數(shù)據(jù)庫中的記錄)時,就會發(fā)生嵌套替換:
$data = [
'blog_title' => 'My Blog Title',
'blog_heading' => 'My Blog Heading',
'blog_entry' => [
'title' => 'Title 1', 'body' => 'Body 1'
]
];
echo $parser->setData($data)
->render('blog_template');
偽變量的值blog_entry
是一個關聯(lián)數(shù)組。在其中定義的鍵/值對將在該變量的變量對循環(huán)內(nèi)公開。
A blog_template
可能適用于上述情況:
<h1>{blog_title} - {blog_heading}</h1>
{blog_entry}
<div>
<h2>{title}</h2>
<p>{body}</p>
</div>
{/blog_entry}
如果您希望在“ blog_entry”范圍內(nèi)可以訪問其他偽變量,請確保將“ cascadeData”選項設置為true。
您可以通過將注釋包裝在符號中來在模板中放置將被忽略和刪除的注釋。{# #}
{# This comment is removed during parsing. #}
{blog_entry}
<div>
<h2>{title}</h2>
<p>{body}</p>
</div>
{/blog_entry}
通過嵌套和循環(huán)替換,您可以選擇將數(shù)據(jù)對級聯(lián)到內(nèi)部替換中。
以下示例不受級聯(lián)的影響:
$template = '{name} lives in {location}{city} on {planet}{/location}.';
$data = [
'name' => 'George',
'location' => [ 'city' => 'Red City', 'planet' => 'Mars' ]
];
echo $parser->setData($data)->renderString($template);
// Result: George lives in Red City on Mars.
此示例根據(jù)級聯(lián)給出不同的結(jié)果:
$template = '{location}{name} lives in {city} on {planet}{/location}.';
$data = [
'name' => 'George',
'location' => [ 'city' => 'Red City', 'planet' => 'Mars' ]
];
echo $parser->setData($data)->renderString($template, ['cascadeData'=>false]);
// Result: {name} lives in Red City on Mars.
echo $parser->setData($data)->renderString($template, ['cascadeData'=>true]);
// Result: George lives in Red City on Mars.
您可以指定頁面的某些部分不使用{noparse}{/noparse}
標記對進行解析。本節(jié)中的所有內(nèi)容將保持原樣,并且括號之間的標記不會發(fā)生任何變量替換,循環(huán)等。
{noparse}
<h1>Untouched Code</h1>
{/noparse}
解析器類支持一些基本的條件語句來處理if
,else
和elseif
語法。所有if
塊必須使用endif
標簽關閉:
{if $role=='admin'}
<h1>Welcome, Admin!</h1>
{endif}
在解析過程中,此簡單塊將轉(zhuǎn)換為以下內(nèi)容:
<?php if ($role=='admin'): ?>
<h1>Welcome, Admin!</h1>
<?php endif ?>
if語句中使用的所有變量必須事先設置為相同的名稱。除此之外,它被完全視為標準PHP條件,所有標準PHP規(guī)則都將在此處適用。你可以使用任何比較運算符你通常會一樣的==
,===
,!==
,<
,>
,等。
{if $role=='admin'}
<h1>Welcome, Admin</h1>
{elseif $role=='moderator'}
<h1>Welcome, Moderator</h1>
{else}
<h1>Welcome, User</h1>
{endif}
注解
在后臺,使用eval()解析條件語句,因此您必須確保注意在條件語句中使用的用戶數(shù)據(jù),否則可能會使應用程序面臨安全風險。
默認情況下,所有變量替換均被轉(zhuǎn)義,以幫助防止對頁面進行XSS攻擊。CodeIgniter的esc
方法支持幾種不同的上下文,例如常規(guī) html ,如果它位于HTML attr 中,則位于 css 等中。如果未指定其他內(nèi)容,則將假定數(shù)據(jù)位于HTML上下文中。您可以使用 esc 過濾器指定使用的上下文:
{ user_styles | esc(css) }
<a href="{ user_link | esc(attr) }">{ title }</a>
有時候,您絕對需要使用某些東西而又不能逃脫。您可以通過在左括號和右括號中添加感嘆號來做到這一點:
{! unescaped_var !}
任何單個變量替換都可以應用一個或多個過濾器以修改其表示方式。這些并不是要大幅度改變輸出,而是提供重用相同變量數(shù)據(jù)但使用不同表示的方法。上面討論的esc過濾器是一個示例。日期是另一個常見用例,您可能需要在同一頁面上的多個部分中以不同的方式設置相同數(shù)據(jù)的格式。
過濾器是偽變量名稱之后的命令,并用豎線符號分隔|
:
// -55 is displayed as 55
{ value|abs }
如果參數(shù)接受任何參數(shù),則必須用逗號分隔并用括號括起來:
{ created_at|date(Y-m-d) }
通過將多個過濾器管道連接在一起,可以將多個過濾器應用于該值。它們從左到右依次處理:
{ created_at|date_modify(+5 days)|date(Y-m-d) }
使用解析器時,可以使用以下過濾器:
Filter | Arguments | Description | Example |
---|---|---|---|
abs | 顯示數(shù)字的絕對值。 | { v/abs } | |
capitalize | 在以下情況下顯示字符串:首字母大寫的所有小寫字母。 | { v/capitalize} | |
date | format (Y-m-d) | PHP 日期兼容的格式字符串。 | { v/date(Y-m-d) } |
date_modify | value to add / subtract | 與strtotime兼容的字符串,用于修改日期,例如或。+5 day``-1 week |
{ v/date_modify(+1 day) } |
default | default value | 如果變量為空或未定義,則顯示默認值。 | { v/default(just in case) } |
esc | html, attr, css, js | 指定用于轉(zhuǎn)義數(shù)據(jù)的上下文。 | { v/esc(attr) } |
excerpt | phrase, radius | 返回給定短語中單詞半徑內(nèi)的文本。與摘錄助手功能相同。 | { v/excerpt(green giant, 20) } |
highlight | phrase | 使用“ <mark> </ mark>”標簽突出顯示文本中的給定短語。 | { v/highlight(view parser) } |
highlight_code | 用HTML / CSS突出顯示代碼示例。 | { v/highlight_code } | |
limit_chars | limit | 將字符數(shù)限制為$ limit。 | { v/limit_chars(100) } |
limit_words | limit | 將字數(shù)限制為$ limit。 | { v/limit_words(20) } |
local_currency | currency, locale | 顯示貨幣的本地化版本?!柏泿拧敝凳侨魏?個字母的ISO 4217貨幣代碼。 | { v/local_currency(EUR,en_US) } |
local_number | type, precision, locale | 顯示數(shù)字的本地化版本?!邦愋汀笨梢允且韵轮唬盒?shù),貨幣,百分比,科學,拼寫,序數(shù),持續(xù)時間。 | { v/local_number(decimal,2,en_US) } |
lower | 將字符串轉(zhuǎn)換為小寫。 | { v/lower } | |
nl2br | 將所有換行符(n)替換為HTML <br/>標記。 | { v/nl2br } | |
number_format | places | 包裝PHP number_format函數(shù)以在解析器中使用。 | { v/number_format(3) } |
prose | 接受一段文字,并使用auto_typography() 方法將其轉(zhuǎn)換為更漂亮,更易于閱讀的散文。 | { v/prose } | |
round | places, type | 將數(shù)字四舍五入到指定位置??梢詡鬟fceil 和floor類型來使用這些功能。 | { v/round(3) } { v/round(ceil) } |
strip_tags | allowed chars | 包裝PHP strip_tags。可以接受一串允許的標簽。 | { v/strip_tags( ) } |
title | 顯示字符串的“標題大小寫”版本,所有字母均小寫,每個單詞均大寫。 | { v/title } | |
upper | 以大寫形式顯示字符串。 | { v/upper } |
有關“ local_number”過濾器的詳細信息,請參見PHP的NumberFormatter。
您可以通過編輯app / Config / View.php并將新條目添加到 $filters
數(shù)組中來輕松創(chuàng)建自己的過濾器。每個鍵都是在視圖中由調(diào)用的過濾器的名稱,其值是任何可調(diào)用的有效PHP:
public $filters = [
'abs' => '\CodeIgniter\View\Filters::abs',
'capitalize' => '\CodeIgniter\View\Filters::capitalize',
];
您可以通過編輯app / Config / View.php并將新條目添加到 $filters
數(shù)組中來使用本機php函數(shù)作為過濾器,每個鍵是在視圖中調(diào)用by的本機PHP函數(shù)的名稱,其值是任何有效的本機PHP功能前綴:
public $filters = [
'str_repeat' => '\str_repeat',
];
插件允許您擴展解析器,為每個項目添加自定義功能。它們可以是任何可調(diào)用的PHP,使其易于實現(xiàn)。在模板內(nèi),插件由標簽指定:{+ +}
{+ foo +} inner content {+ /foo +}
此示例顯示了一個名為foo的插件。它可以在其開始標記和結(jié)束標記之間操縱任何內(nèi)容。在此示例中,它可以使用文本“內(nèi)部內(nèi)容”。在進行任何偽變量替換之前,將處理插件。
盡管插件通常由標簽對組成,如上所示,但它們也可以是單個標簽,沒有結(jié)束標簽:
{+ foo +}
開頭標簽還可以包含可以自定義插件工作方式的參數(shù)。參數(shù)表示為鍵/值對:
{+ foo bar=2 baz="x y" }
參數(shù)也可以是單個值:
{+ include somefile.php +}
使用解析器時,可以使用以下插件:
Plugin | Arguments | Description | Example |
---|---|---|---|
current_url | current_url輔助函數(shù)的別名。 | {+ current_url +} | |
previous_url | previous_url輔助函數(shù)的別名。 | {+ previous_url +} | |
siteURL | site_url幫助器功能的別名。 | {+ siteURL “l(fā)ogin” +} | |
mailto | email, title, attributes | mailto助手功能的別名。 | {+ mailto email=foo@example.com title=”Stranger Things” +} |
safe_mailto | email, title, attributes | safe_mailto幫助程序功能的別名。 | {+ safe_mailto email=foo@example.com title=”Stranger Things” +} |
lang | language string | lang助手功能的別名。 | {+ lang number.terabyteAbbr +} |
validation_errors | fieldname(optional) | 返回該字段的錯誤字符串(如果已指定)或所有驗證錯誤。 | {+ validation_errors +} , {+ validation_errors field=”email” +} |
route | route name | route_to輔助函數(shù)的別名。 | {+ route “l(fā)ogin” +} |
最簡單的方法是,注冊一個新插件并準備使用,只需將其添加到 $ plugins數(shù)組下的app / Config / View.php中。密鑰是模板文件中使用的插件的名稱。該值是任何可調(diào)用的有效PHP,包括靜態(tài)類方法和閉包:
public $plugins = [
'foo' => '\Some\Class::methodName',
'bar' => function($str, array $params=[]) {
return $str;
},
];
必須在配置文件的構(gòu)造函數(shù)中定義正在使用的所有閉包:
class View extends \CodeIgniter\Config\View
{
public $plugins = [];
public function __construct()
{
$this->plugins['bar'] = function(array $params=[]) {
return $params[0] ?? '';
};
parent::__construct();
}
}
如果可調(diào)用項是單獨的,則將其視為單個標簽,而不是打開/關閉標簽。它將由插件的返回值替換:
public $plugins = [
'foo' => '\Some\Class::methodName'
];
// Tag is replaced by the return value of Some\Class::methodName static function.
{+ foo +}
如果可調(diào)用對象包裝在數(shù)組中,則將其視為可以在其標簽之間的任何內(nèi)容上進行操作的打開/關閉標簽對:
public $plugins = [
'foo' => ['\Some\Class::methodName']
];
{+ foo +} inner content {+ /foo +}
如果您包含模板中未引用的替換參數(shù),則將忽略它們:
$template = 'Hello, {firstname} {lastname}';
$data = [
'title' => 'Mr',
'firstname' => 'John',
'lastname' => 'Doe'
];
echo $parser->setData($data)
->renderString($template);
// Result: Hello, John Doe
如果您不包含模板中引用的替換參數(shù),則結(jié)果中將顯示原始的偽變量:
$template = 'Hello, {firstname} {initials} {lastname}';
$data = [
'title' => 'Mr',
'firstname' => 'John',
'lastname' => 'Doe'
];
echo $parser->setData($data)
->renderString($template);
// Result: Hello, John {initials} Doe
如果在需要數(shù)組時(例如,對變量對)提供字符串替換參數(shù),那么將對開頭變量對標記進行替換,但是結(jié)尾變量對標記無法正確呈現(xiàn):
$template = 'Hello, {firstname} {lastname} ({degrees}{degree} {/degrees})';
$data = [
'degrees' => 'Mr',
'firstname' => 'John',
'lastname' => 'Doe',
'titles' => [
['degree' => 'BSc'],
['degree' => 'PhD']
]
];
echo $parser->setData($data)
->renderString($template);
// Result: Hello, John Doe (Mr{degree} {/degrees})
您不必使用變量對就可以在視圖中獲得迭代的效果??梢詫⒁晥D片段用于變量對內(nèi)部,并可以在控制器中而不是視圖中控制迭代。
在視圖中控制迭代的示例:
$template = '<ul>{menuitems}
<li><a href="{link}">{title}</a></li>
{/menuitems}</ul>';
$data = [
'menuitems' => [
['title' => 'First Link', 'link' => '/first'],
['title' => 'Second Link', 'link' => '/second'],
]
];
echo $parser->setData($data)
->renderString($template);
結(jié)果:
<ul>
<li><a href="/first">First Link</a></li>
<li><a href="/second">Second Link</a></li>
</ul>
一個使用視圖片段在控制器中控制迭代的示例:
$temp = '';
$template1 = '<li><a href="{link}">{title}</a></li>';
$data1 = [
['title' => 'First Link', 'link' => '/first'],
['title' => 'Second Link', 'link' => '/second'],
];
foreach ($data1 as $menuItem)
{
$temp .= $parser->setData($menuItem)->renderString($template1);
}
$template2 = '<ul>{menuitems}</ul>';
$data = [
'menuitems' => $temp
];
echo $parser->setData($data)
->renderString($template2);
結(jié)果:
<ul>
<li><a href="/first">First Link</a></li>
<li><a href="/second">Second Link</a></li>
</ul>
CodeIgniter\View\Parser
render
($ view [,$ options [,$ saveData = false]]] )
參數(shù): | $ view(string)–視圖源的文件名 |
---|---|
$ options(array)– **選項**數(shù)組,作為鍵/值對 | |
$ saveData(boolean)–如果為true,則將保存數(shù)據(jù)以供任何其他調(diào)用使用;如果為false,則在渲染視圖后將清理數(shù)據(jù)。 | |
返回: | 所選視圖的渲染文本 |
返回類型: | 串 |
根據(jù)文件名和任何已設置的數(shù)據(jù)構(gòu)建輸出:
echo $parser->render('myview');
支持的選項:
cache
-保存視圖結(jié)果的時間(以秒為單位)cache_name
-用于保存/檢索緩存的視圖結(jié)果的ID;默認為viewpathcascadeData
-如果應傳播發(fā)生嵌套或循環(huán)替換時有效的數(shù)據(jù)對,則為truesaveData
-如果應保留視圖數(shù)據(jù)參數(shù)以供后續(xù)調(diào)用,則為trueleftDelimiter
-用于偽變量語法的左定界符rightDelimiter
-在偽變量語法中使用的正確定界符首先執(zhí)行任何條件替換,然后為每個數(shù)據(jù)對執(zhí)行其余替換。
renderString
($ template [,$ options [,$ saveData = false]]] )
參數(shù): | $ template(string)–查看以字符串形式提供的源代碼 |
---|---|
$ options(array)– **選項**數(shù)組,作為鍵/值對 | |
$ saveData(boolean)–如果為true,則將保存數(shù)據(jù)以供任何其他調(diào)用使用;如果為false,則在渲染視圖后將清理數(shù)據(jù)。 | |
返回: | 所選視圖的渲染文本 |
返回類型: | 串 |
根據(jù)提供的模板源和任何已設置的數(shù)據(jù)來構(gòu)建輸出:
echo $parser->render('myview');
支持的選項和行為如上所述。
setData
([$data[,$ context = null]])
參數(shù): | $ data(array)–視圖數(shù)據(jù)字符串的數(shù)組,作為鍵/值對 |
---|---|
$ context(string)–用于數(shù)據(jù)轉(zhuǎn)義的上下文。 | |
返回: | 渲染器,用于方法鏈接 |
返回類型: | CodeIgniter \ View \ RendererInterface。 |
一次設置幾條視圖數(shù)據(jù):
$renderer->setData(['name'=>'George', 'position'=>'Boss']);
支持的轉(zhuǎn)義上下文:html,css,js,url或attr或raw。
如果“原始”,將不會發(fā)生轉(zhuǎn)義。
setVar
($name[,$ value = null[,$ context = null]])
參數(shù): | $ name(string)–視圖數(shù)據(jù)變量的名稱 |
---|---|
$ value(mixed)–此視圖數(shù)據(jù)的值 | |
$ context(string)–用于數(shù)據(jù)轉(zhuǎn)義的上下文。 | |
返回: | 渲染器,用于方法鏈接 |
返回類型: | CodeIgniter \ View \ RendererInterface。 |
設置單個視圖數(shù)據(jù):
$renderer->setVar('name','Joe','html');
支持的轉(zhuǎn)義上下文:html,css,js,url,attr或raw。
如果“原始”,將不會發(fā)生轉(zhuǎn)義。
setDelimiters
($ leftDelimiter ='{',$ rightDelimiter ='}' )
參數(shù): | $ leftDelimiter(string)–替換字段的左定界符 |
---|---|
$ rightDelimiter(string)–替換字段的右定界符 | |
返回: | 渲染器,用于方法鏈接 |
返回類型: | CodeIgniter \ View \ RendererInterface。 |
替代替換字段定界符:
$renderer->setDelimiters('[',']');
更多建議: