W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
XHP提供您的輸出(通常為HTML)的本機XML樣表示。這樣可以對您的UI代碼進(jìn)行類型檢查,并自動避免多個常見問題,如跨站點腳本(XSS)和雙重轉(zhuǎn)義。它還應(yīng)用其他驗證規(guī)則,例如<head>必須包含<title>。
使用傳統(tǒng)插值,一個簡單的頁面可能如下所示:
<?hh
$ user_name = 'Fred' ;
echo “<tt> Hello <strong> $ user_name </ strong> </ tt>” ;
然而,使用XHP,它看起來像這樣:
<?hh
$ user_name = 'Fred' ;
echo < tt > Hello < strong > { $ user_name } </ strong > </ tt > ;
第一個例子使用字符串插值來輸出HTML,而第二個例子沒有引號,這意味著Hack完全可以理解語法 - 但這并不意味著你需要做的只是刪除引號。所需的其他步驟包括:
XHP目前有幾個命名空間的問題; 我們建議:
我們計劃在未來支持namespaces。
雖然XHP語法是Hack的一部分,但很大一部分實現(xiàn)是在一個名為XHP-Lib的普通庫中,需要通過編寫器來安裝:
“require”:{
“facebook / xhp-lib”:“?2.2”
}
這包括基類和接口以及標(biāo)準(zhǔn)HTML元素的定義。
大多數(shù)用戶的初始原因是因為它是“默認(rèn)安全”:所有變量都以上下文相適應(yīng)的方式自動轉(zhuǎn)義(例如,有不同的轉(zhuǎn)義屬性值與文本節(jié)點的規(guī)則)。另外,XHP被類型檢查器理解,確保不傳遞屬性值。一個常見的例子是border="3",但是border是一個on / off屬性,所以3的值沒有意義。
對于XHP經(jīng)驗豐富的用戶來說,最大的優(yōu)點是可以輕松地添加自定義的“元素”,使用自己的行為,然后可以像純HTML元素一樣使用。例如,該網(wǎng)站定義<a:post>了與標(biāo)準(zhǔn)<a>標(biāo)簽具有相同接口的標(biāo)簽,但是使用POST請求而不是GET請求:
<?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;
}
}
需要一點CSS,以便<form>
不創(chuàng)建塊元素:
form.postLink {
display:inline;
}
在這一點上,新元素可以像任何內(nèi)置元素一樣使用:
<?hh
function intro_examples_a_a_post() {
$get_link =
<a rel="external nofollow" target="_blank" >I'm a normal link</a>;
$post_link =
<a:post 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" >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對象是一流的,而不僅僅是字符串,因此可以進(jìn)行一整套驗證,以確保您的UI沒有細(xì)微的錯誤:
<?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
上述代碼將不會進(jìn)行類型檢查或運行,因為XHP驗證器將會看到<span>
并且<naps>
標(biāo)簽不匹配 - 但是以下代碼將正確鍵入正確但無法運行,因為在標(biāo)記匹配時,它們不能正確嵌套(根據(jù)HTML規(guī)范),并且嵌套驗證僅在運行時發(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]"
基于字符串的條目和驗證是跨站點腳本(XSS)的首選。你可以通過使用特殊功能來解決這個問題htmlspecialchars(),但是你必須真正記住使用這些功能。輸出之前,XHP自動將保留的HTML字符轉(zhuǎn)義為HTML實體。
<?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號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: