Home >Backend Development >PHP Tutorial >php shtmlspecialchars function detailed explanation_PHP tutorial

php shtmlspecialchars function detailed explanation_PHP tutorial

WBOY
WBOYOriginal
2016-07-13 17:53:00866browse

由于还是码农新人,所以还未开始正式的编写大的工程代码,所以老员工给了我一个去年写的大的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);
echo $string1;
echo '
';
echo $string2;
?>

The output results are

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

The result is to just replace $amp; with & and leave the rest unchanged.

This can solve the above problem 1. Can you take out the #? If you take out the #, it means that the &# will be replaced with &, and then you have to write '\ 1', that’s fine, but it doesn’t feel right

Is this unnecessary? Yes!

Appendix:

html character table

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


作者:wolinxuebin

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/478078.htmlTechArticle由于还是码农新人,所以还未开始正式的编写大的工程代码,所以老员工给了我一个去年写的大的PHP工程的工程代码,先看下。抱着必须扫...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn