ホームページ >バックエンド開発 >PHPチュートリアル >php shtmlspecialchars関数詳細解説_PHPチュートリアル

php shtmlspecialchars関数詳細解説_PHPチュートリアル

WBOY
WBOYオリジナル
2016-07-13 17:53:00863ブラウズ

由于还是码农新人,所以还未开始正式的编写大的工程代码,所以老员工给了我一个去年写的大的PHP工程的工程代码,先看下。抱着必须扫清每个死角的心里,下午碰到了

shtmlspecialchars()函数,网上一查挺多人都在用的,但不是PHP自带的,而是莫比较官方的写的。但是这里面的正则表达式着实让我纠结了一方,不讲废话了,切入正题。

[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进制数字组成的字符串。


根据第一条,我们应该写出正则表达式:&#/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)

这里,前面的正则表达式已经很清楚了,但是作者又后面的&\\1搞晕了,什么意思呀?

经查证\1代表正则表达式的第一个括号内的内容。

自己写了一个测试

[php]

$string = 'x10p'; $string1 = preg_replace('/(x)([0-9]+)p/', '&\1',$string); $string2 = preg_replace('/x([0-9]+)p/', '&\1',$string); $string1 をエコーし​​ます。 エコー '
'; $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' と書かなければなりません。 、それはいいけど、気分が悪い

これは不要ですか?はい!

付録:

エンティティ十进制コードという名前の特別なコード αα;  Α  Β&β;  Β  Γ &ガンマ; 
Δ Δ  Δ  Εとイプシロン。  Ε  Ζとゼータ。 
Η &η;  Η  Θ&シータ;  Θ  I&Iota; 
Κとカッパ。  Κ  Λ Λ  Λ  Μ&イン; 
Ν Ν  Ν  ΞΞ  Ξ  Ο&OM; 
ΠΠ  Π  Ρ Ρ  Ρ  ΣΣ; 
Τ &タウ;  Τ  Υ&ウプシロン;  Υ  ΦΦ 
Χ&ち;  Χ  Ψとプサイ;  Ψ  Ω&オメガ; 
αα  α  β・β  β  γ γ 
δδ  δ  εε  ε  ゼータ & ゼータ; 
η&η;  η  θθ  θ  ι ι 
κ &κ;  κ  λ とラムダ。  λ  μμ 
νν  ν  ξ ξ  ξ  ο & ミクロン; 
ππ  π  ρ&ρ;  ρ  σσ 
σσ  σ  τ τ  τ  υε; 
φφ  φ  χχ  χ  ψ ψ; 
ωω;  ω  ϑ θsym;  ϑ  ϒ ϒ 
ϖ ϖ  ϖ  •&ブル;  •  … … 
「アンドプライム」  ′  '' ″  ″  ‾ ‾ 
⁄ ⁄  ⁄  ℘ ℘  ℘  ℑ ℑ 
ℜ ℜ  ℜ  ™&トレード;  ™  ℵ ℵ 
←「ラー」  ←  ↑「」  ↑  →「」 
↓ ↓  ↓  ↔ &ハール;  ↔  ↵ ↵ 
⇐ ⇐  ⇐  ⇑ ⇑  ⇑  ⇒ ⇒ 
⇓ ⇓  ⇓  ⇔ &hああ;  ⇔  ∀ ∀ 
∂ ∂  ∂  ∃ &存在します。  ∃  ∅&空; 
∇ ∇  ∇  ∈ ∈  ∈  ∉ ∉ 
∋ ∋  ∋  ∏ ∏  ∏  ∑ ∑ 
− &マイナス;  −  ∗ &ロースト;  ∗  √ √ 
∝ ∝  ∝  ∞ ∞  ∞  ∠& 
∧ ∧  ⊥  ∨ ∨  ⊦  ∩ ∩ 
∪&カップ;  ∪  ∫ ∫  ∫  ∴ ∴ 
〜 ∼  ∼  ≅ ≅  ≅  ≈ ≈ 
≠  ≠  ≠  ≡  ≡  ≡  ≤  ≤  ≤
≥  ≥  ≥  ⊂  ⊂  ⊂  ⊃  ⊃  ⊃
⊄  ⊄  ⊄  ⊆  ⊆  ⊆  ⊇  ⊇  ⊇
⊕  ⊕  ⊕  ⊗  ⊗  ⊗  ⊥  ⊥  ⊥
⋅  ⋅  ⋅  ⌈  ⌈  ⌈  ⌉  ⌉  ⌉
⌊  ⌊  ⌊  ⌋  ⌋  ⌋  ◊  ◊  ◊
♠  ♠  ♠  ♣  ♣  ♣  ♥  ♥  ♥
♦  ♦  ♦          ¡  ¡  ¡
¢  ¢  ¢  £  £  £  ¤  ¤  ¤
¥  ¥  ¥  ¦  ¦  ¦  §  §  §
¨  ¨  ¨  ©  ©  ©  ª  ª  ª
«  «  «  ¬  ¬  ¬     ­  ­
®  ®  ®  ¯  ¯  ¯  °  °  °
±  ±  ±  ²  ²  ²  ³  ³  ³
´  ´  ´  µ  µ  µ  "  "  "
< < < >  >  >  '     '


作者:wolinxuebin

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/478078.htmlTechArticle由于还是码农新人,所以还未开始正式的编写大的工程代码,所以老员工给了我一个去年写的大的PHP工程的工程代码,先看下。抱着必须扫...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。