W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
XHP提供您的輸出(通常為HTML)的本機(jī)XML樣表示。這樣可以對(duì)您的UI代碼進(jìn)行類(lèi)型檢查,并自動(dòng)避免多個(gè)常見(jiàn)問(wèn)題,如跨站點(diǎn)腳本(XSS)和雙重轉(zhuǎn)義。它還應(yīng)用其他驗(yàn)證規(guī)則,例如<head>必須包含<title>。
使用傳統(tǒng)插值,一個(gè)簡(jiǎn)單的頁(yè)面可能如下所示:
<?hh
$ user_name = 'Fred' ;
echo “<tt> Hello <strong> $ user_name </ strong> </ tt>” ;
然而,使用XHP,它看起來(lái)像這樣:
<?hh
$ user_name = 'Fred' ;
echo < tt > Hello < strong > { $ user_name } </ strong > </ tt > ;
第一個(gè)例子使用字符串插值來(lái)輸出HTML,而第二個(gè)例子沒(méi)有引號(hào),這意味著Hack完全可以理解語(yǔ)法 - 但這并不意味著你需要做的只是刪除引號(hào)。所需的其他步驟包括:
XHP目前有幾個(gè)命名空間的問(wèn)題; 我們建議:
我們計(jì)劃在未來(lái)支持namespaces。
雖然XHP語(yǔ)法是Hack的一部分,但很大一部分實(shí)現(xiàn)是在一個(gè)名為XHP-Lib的普通庫(kù)中,需要通過(guò)編寫(xiě)器來(lái)安裝:
“require”:{
“facebook / xhp-lib”:“?2.2”
}
這包括基類(lèi)和接口以及標(biāo)準(zhǔn)HTML元素的定義。
大多數(shù)用戶的初始原因是因?yàn)樗恰澳J(rèn)安全”:所有變量都以上下文相適應(yīng)的方式自動(dòng)轉(zhuǎn)義(例如,有不同的轉(zhuǎn)義屬性值與文本節(jié)點(diǎn)的規(guī)則)。另外,XHP被類(lèi)型檢查器理解,確保不傳遞屬性值。一個(gè)常見(jiàn)的例子是border="3",但是border是一個(gè)on / off屬性,所以3的值沒(méi)有意義。
對(duì)于XHP經(jīng)驗(yàn)豐富的用戶來(lái)說(shuō),最大的優(yōu)點(diǎn)是可以輕松地添加自定義的“元素”,使用自己的行為,然后可以像純HTML元素一樣使用。例如,該網(wǎng)站定義<a:post>了與標(biāo)準(zhǔn)<a>標(biāo)簽具有相同接口的標(biāo)簽,但是使用POST請(qǐng)求而不是GET請(qǐng)求:
<?hh // strict
final class :a:post extends :x:element {
attribute :a;
use XHPHelpers;
protected function render(): XHPRoot {
$id = $this->getID();
$anchor = <a>{$this->getChildren()}</a>;
$form = (
<form
id={$id}
method="post"
action={$this->:href}
target={$this->:target}
class="postLink"
>{$anchor}</form>
);
$this->transferAllAttributes($anchor);
$anchor->setAttribute(
'onclick',
'document.getElementById("'.$id.'").submit(); return false;',
);
$anchor->setAttribute('href', '#');
return $form;
}
}
需要一點(diǎn)CSS,以便<form>
不創(chuàng)建塊元素:
form.postLink {
display:inline;
}
在這一點(diǎn)上,新元素可以像任何內(nèi)置元素一樣使用:
<?hh
function intro_examples_a_a_post() {
$get_link =
<a rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" >I'm a normal link</a>;
$post_link =
<a:post rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" >I make a POST REQUEST</a:post>;
echo $get_link;
echo "\n";
echo $post_link;
}
intro_examples_a_a_post();
Output
<a rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" >I'm a normal link</a>
<form id="f20194a67b" method="post" action="http://www.example.com" class="postLink"><a href="#" id="f20194a67b" onclick="document.getElementById("f20194a67b").submit(); return false;">I make a POST REQUEST</a></form>
由于XHP對(duì)象是一流的,而不僅僅是字符串,因此可以進(jìn)行一整套驗(yàn)證,以確保您的UI沒(méi)有細(xì)微的錯(cuò)誤:
<?hh
function intro_examples_tag_matching_validation_using_string(): void {
echo '<div class="section-header">';
echo '<a href="#use">You should have used <span class="xhp">XHP</naps></a>';
echo '</div>';
}
function intro_examples_tag_matching_validation_using_xhp(): void {
// Typechecker error
// Fatal syntax error at runtime
echo
<div class="section-header">
<a href="#use">You should have used <span class="xhp">XHP</naps></a>
</div>;
}
function intro_examples_tag_matching_validation_run(): void {
intro_examples_tag_matching_validation_using_string();
intro_examples_tag_matching_validation_using_xhp();
}
intro_examples_tag_matching_validation_run();
Output
Fatal error: XHP: mismatched tag: 'naps' not the same as 'span' in /data/users/joelm/user-documentation/guides/hack/24-XHP/01-introduction-examples/tag-matching-validation.php.type-errors on line 14
上述代碼將不會(huì)進(jìn)行類(lèi)型檢查或運(yùn)行,因?yàn)閄HP驗(yàn)證器將會(huì)看到<span>
并且<naps>
標(biāo)簽不匹配 - 但是以下代碼將正確鍵入正確但無(wú)法運(yùn)行,因?yàn)樵跇?biāo)記匹配時(shí),它們不能正確嵌套(根據(jù)HTML規(guī)范),并且嵌套驗(yàn)證僅在運(yùn)行時(shí)發(fā)生:
?hh
function intro_examples_allowed_tag_validation_using_string(): void {
echo '<ul><i>Item 1</i></ul>';
}
function intro_examples_allowed_tag_validation_using_xhp(): void {
try {
echo <ul><i>Item 1</i></ul>;
} catch (\XHPInvalidChildrenException $ex) {
// We will get here because an <i> cannot be nested directly below a <ul>
var_dump($ex->getMessage());
}
}
function intro_examples_allowed_tag_validation_run(): void {
intro_examples_allowed_tag_validation_using_string();
echo PHP_EOL . PHP_EOL;
intro_examples_allowed_tag_validation_using_xhp();
}
intro_examples_allowed_tag_validation_run();
Output
<ul><i>Item 1</i></ul>
string(262) "Element `ul` was rendered with invalid children.
/data/users/joelm/user-documentation/guides/hack/24-XHP/01-introduction-examples/allowed-tag-validation.php:11
Verified 0 children before failing.
Children expected:
(:li)*
Children received:
:i[%flow,%phrase]"
基于字符串的條目和驗(yàn)證是跨站點(diǎn)腳本(XSS)的首選。你可以通過(guò)使用特殊功能來(lái)解決這個(gè)問(wèn)題htmlspecialchars(),但是你必須真正記住使用這些功能。輸出之前,XHP自動(dòng)將保留的HTML字符轉(zhuǎn)義為HTML實(shí)體。
<?hh
function intro_examples_avoid_xss_using_string(string $could_be_bad): void {
// Could call htmlspecialchars() here
echo '<html><head/><body> ' . $could_be_bad . '</body></html>';
}
function intro_examples_avoid_xss_using_xhp(string $could_be_bad): void {
// The string $could_be_bad will be escaped to HTML entities like:
// <html><head></head><body><blink>Ugh</blink></body></html>
echo
<html>
<head/>
<body>{$could_be_bad}</body>
</html>;
}
function intro_examples_avoid_xss_run(string $could_be_bad): void {
intro_examples_avoid_xss_using_string($could_be_bad);
echo PHP_EOL . PHP_EOL;
intro_examples_avoid_xss_using_xhp($could_be_bad);
}
intro_examples_avoid_xss_run('<blink>Ugh</blink>');
Output
<html><head/><body> <blink>Ugh</blink></body></html>
<html><head></head><body><blink>Ugh</blink></body></html>
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: