php shtmlspecialchars 函數 詳解_PHP教程

來源:互聯網
上載者:User
由於還是碼農新人,所以還未開始正式的編寫大的工程代碼,所以老員工給了我一個去年寫的大的PHP工程的工程代碼,先看下。抱著必須掃清每個死角的心裡,下午碰到了

shtmlspecialchars()函數,網上一查挺多人都在用的,但不是PHP內建的,而是莫比較官方的寫的。但是這裡面的Regex著實讓我糾結了一方,不講廢話了,切入正題。

[php]
function shtmlspecialchars($string) {
if(is_array($string)) {
foreach($string as $key => $val) {
$string[$key] = shtmlspecialchars($val);
}
} else {
$string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/', '&\\1',
str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string));
}
return $string;
}

以上就是shtmlspecialchars()函數的定義,其他的不講,就講這句讓很多人揪心的

[php]
$string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/', '&\\1',
str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string));


這裡先介紹下這個函數的作用:

html中可能出現的四種特殊字元進行轉義,分別是

&轉&

"轉"

<轉<

>轉<(ps:這個後面的分號";"是連在一起的,一個整體,不是作者為了分隔用的)


這與PHP內建的htmlspecialchars()效果剛好相反。


那麼一般人裡面會用下面的代碼實現這個函數所要實現的功能

[php]
str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string));

但是等一等!


問:等什嗎?不是已經完成了這個功能了?

答:錯,大錯,特錯了,你這叫寧可枉殺3000,不放過一個,不人道的呀。

問:哪裡錯了?

答:情況下面的內容!

如果僅僅用上面的函數,那麼會將html特殊字元和unicode編碼都破壞掉這可不是我們要的結果,具體字元表見文章後面的附件。

有人觀察了字元表的所有資料,最後得出下面的結論:

1、html特殊字元都是由&#開頭後面加3-5個數字或者&#開頭加一個字元和2-5個字元或數字組成的字串
2、unicode編碼是以&#開頭後面加4個16進位數字組成的字串。


根據第一條,我們應該寫出Regex:&#/d{3,5}|[a-zA-Z][a-zA-Z0-9]{2,5};(ps:這個也是內建分號";"的)

根據第二條,可以得出&#[a-fA-F0-9]{4}; (ps:因為16進位是從0-f)


又由於前面的操作已經把&替換成了&所以講上面兩條整合下就出了下面的

/&((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/

問題1:
有人問,是不是可以寫成下面的樣子

/&#(((\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/

把井號提出來,當然可以,不過如果你要這樣寫,後面的再提,有些下改動。

我們把第一步操作
[php]
str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string));

結果寫成$string

那麼反替換我們就可以簡略的寫成

preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/', '&\\1',$string)

這裡,前面的Regex已經很清楚了,但是作者又後面的&\\1搞暈了,什麼意思呀?

經查證\1代表Regex的第一個括弧內的內容。

自己寫了一個測試

[php]

$string = 'x10p';
$string1 = preg_replace('/(x)([0-9]+)p/', '&\\1',$string);
$string2 = preg_replace('/x([0-9]+)p/', '&\\1',$string);
echo $string1;
echo '
';
echo $string2;
?>

輸出的結果分別是

&x 第一括弧內的是 x
&10 第一括弧內的是10
[php]
preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/', '&\\1',$string)

結果就是僅僅把$amp;替換為&而後面的保留不變。

到這可以解決上面的問題1,是否可以把#拿出來,如果你吧#拿出來的話,那麼就是說會將&#都用&替換,然後後面的你得寫'&#\\1',這樣就可以,不過是不是感覺

多此一舉了?是的!

附錄:

html 字元表

特殊符號 具名實體 十進位編碼 特殊符號 具名實體 十進位編碼 特殊符號 具名實體 十進位編碼
Α Α Α Β Β Β Γ Γ Γ
Δ Δ Δ Ε Ε Ε Ζ Ζ Ζ
Η Η Η Θ Θ Θ Ι Ι Ι
Κ Κ Κ Λ Λ Λ Μ Μ Μ
Ν Ν Ν Ξ Ξ Ξ Ο Ο Ο
Π Π Π Ρ Ρ Ρ Σ Σ Σ
Τ Τ Τ Υ Υ Υ Φ Φ Φ
Χ Χ Χ Ψ Ψ Ψ Ω Ω Ω
α α α β β β γ γ γ
δ δ δ ε ε ε ζ ζ ζ
η η η θ θ θ ι ι ι
κ κ κ λ λ λ μ μ μ
ν ν ν ξ ξ ξ ο ο ο
π π π ρ ρ ρ ς ς ς
σ σ σ τ τ τ υ υ υ
φ φ φ χ χ χ ψ ψ ψ
ω ω ω ϑ ϑ ϑ ϒ ϒ ϒ
ϖ ϖ ϖ • • • … … …
′ ′ ′ ″ ″ ″ ‾ ‾ ‾
⁄ ⁄ ⁄ ℘ ℘ ℘ ℑ ℑ ℑ
ℜ ℜ ℜ ™ ™ ™ ℵ ℵ ℵ
← ← ← ↑ ↑ ↑ → → →
↓ ↓ ↓ ↔ ↔ ↔ ↵ ↵ ↵
⇐ ⇐ ⇐ ⇑ ⇑ ⇑ ⇒ ⇒ ⇒
⇓ ⇓ ⇓ ⇔ ⇔ ⇔ ∀ ∀ ∀
∂ ∂ ∂ ∃ ∃ ∃ ∅ ∅ ∅
∇ ∇ ∇ ∈ ∈ ∈ ∉ ∉ ∉
∋ ∋ ∋ ∏ ∏ ∏ ∑ ∑ −
− − − ∗ ∗ ∗ √ √ √
∝ ∝ ∝ ∞ ∞ ∞ ∠ ∠ ∠
∧ ∧ ⊥ ∨ ∨ ⊦ ∩ ∩ ∩
∪ ∪ ∪ ∫ ∫ ∫ ∴ ∴ ∴
∼ ∼ ∼ ≅ ≅ ≅ ≈ ≈ ≅
≠ ≠ ≠ ≡ ≡ ≡ ≤ ≤ ≤
≥ ≥ ≥ ⊂ ⊂ ⊂ ⊃ ⊃ ⊃
⊄ ⊄ ⊄ ⊆ ⊆ ⊆ ⊇ ⊇ ⊇
⊕ ⊕ ⊕ ⊗ ⊗ ⊗ ⊥ ⊥ ⊥
⋅ ⋅ ⋅ ⌈ ⌈ ⌈ ⌉ ⌉ ⌉
⌊ ⌊ ⌊ ⌋ ⌋ ⌋ ◊ ◊ ◊
♠ ♠ ♠ ♣ ♣ ♣ ♥ ♥ ♥
♦ ♦ ♦   ¡ ¡ ¡
¢ ¢ ¢ £ £ £ ¤ ¤ ¤
¥ ¥ ¥ ¦ ¦ ¦ § § §
¨ ¨ ¨ © © © ª ª ª
« « « ¬ ¬ ¬ ­ ­
® ® ® ¯ ¯ ¯ ° ° °
± ± ± ² ² ² ³ ³ ³
´ ´ ´ µ µ µ " " "
< < < > > > ' '


作者:wolinxuebin

http://www.bkjia.com/PHPjc/478078.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/478078.htmlTechArticle由於還是碼農新人,所以還未開始正式的編寫大的工程代碼,所以老員工給了我一個去年寫的大的PHP工程的工程代碼,先看下。抱著必須掃...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.