在日常开拓中,我们常常碰到这样的问题,即有些PHP问题看似大略,一说就明,但是一到利用时就踩坑。比如,下面我所列的几条:
1、由于利用单引号,以“\r\n”为分割符,利用PHP函数explode分割字符串,不能正常分割。
缘故原由:这个涉及到单引号与双引号的差异,在单引号中反斜杠不能被解析。因此,利用explode分割时,如果利用单引号,\r\n会被当作字符串,而不是换行符,以是此时,不能正常分割。
类似问题还有字符串中包含{}的情形。在字符串中,要想使利用了{}包含的变量成功解析,该字符串必须利用双引号。
2、由于BOM头,利用PHP函数json_decode解析json字符串,不能解析成功。
缘故原由:UTF-8 编码的文件可以分为无 BOM 和 BOM 两种格式。何谓BOM? \公众EF BB BF\"大众 这三个字节就叫BOM,BOM的全称叫做\"大众Byte Order Mard\"大众。在utf-8文件中常用BOM来表明这个文件是UTF-8文件,而BOM的本意实在utf16中用来表示高低字节序列的。在字节流之前有 BOM表示采取低字节序列(低字节在前面),而utf8不用考虑字节序列,以是实在有无BOM都可以。UTF-8以字节为编码单元,没有字节序的问题。 UTF-16以两个字节为编码单元,在阐明一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是 594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是 “奎”还是“乙”?
如果文件保 存时,选择了利用 BOM,会使页面显示不正常。一样平常来说,php是不支持有BOM的,php文件该当保存为UTF-8无BOM类型,以是在保存 UTF8 编码PHP文件时,不要利用 BOM。
3、由于正反斜杠的缘故原由,PHP函数basename利用无效
我们常常利用PHP函数basename,来从一个包含有指向一个文件的全路径的字符串中获取基本的文件名,但是由于正反斜杠的缘故原由,有时你会创造basename函数无法生效,特殊是在window系统和linux系统中切换时。原来,basename函数受操作系统影响,用在 Windows 中,斜线(/)和反斜线(\)都可以用作目录分隔符,而在其它环境下只能是斜线(/)。因此,如果你在window系统下利用的反斜线(\),那到其他系统时是有问题的。
为避免此影响,最好都利用斜线(/)来作为目录分割符,对付利用了命名空间的情形,最好先利用str_replace函数将反斜线(\)更换成斜线(/)。
4、trim系列函数的过多去除
trim函数的基本用法是去除最外边的空格、换行符之类的。由于其可选参数,很多人也会将其用于去除UTF8BOM头、文件扩展名等等,比如 ltrim($str, \"大众\xEF\xBB\xBF\"大众); rtrim($str, \"大众.txt\"大众); 。但是很快,就会创造这些函数会多去除了一些东西,比如本来是想去除后缀的,结果 logtext.txt 会变成了 logte 而不是 logtext。为什么呢?由于后面这个参数的意思不是一个完全字符串,而是字符列表,也便是说会一贯检讨最左/最右是否符合此列表的个中一个。
5、htmlspecialchars 函数默认不转义单引号
不少网站都是利用此函数作为通用的输入过滤函数,但是此函数默认情形是不过滤单引号的。这是非常非常地随意马虎造成XSS漏洞。这样的做法和不过滤双引号没太大差异,只要前端写得轻微有点不规范(用了单引号)就会中招。因此,我们用的时候一定要给这个函数加上参数 htmlspecialchars( $data, ENT_QUOTES)
6、foreach的保留征象
利用 foreach($someArr as $someL){ } 之类的用法时,要把稳末了的一个 $someL 会一贯保留到该函数/方法结束。而当利用引用的时候 foreach($someArr as &$someL){ }这因此引用来保存,也便是说后面若有利用同一个名字的变量名,将会把原数据改变(就像一个乱用的C指针)。为安全起见,建议每个foreach(尤其是引用的)结束之后都利用unset把这些变量打消掉。
7、小数(符点数)不能直接比较是否相等
比如 if( 0.5+0.2==0.7 ) 的结果是 false。究其缘故原由是由于,PHP是基于C措辞的,而C措辞由于其二进制符点数的表示办法,导致不能精确表示大多数符点数。实际上,险些所有的编程措辞都没能精确表示小数(符点数),这是一个普遍存在的征象,由于这个是 IEEE 754 的毛病。想要办理此问题,只能另立标准,彷佛只有Mathematica办理了此问题。
8、字符串是否相同建议用 === 而非 ==
为什么呢?由于这个比较是弱类型。两个比较时,PHP会先考试测验判别旁边两者是否为数字。而问题就在于什么样的字符串是数字,是纯挚的数字串吗?远远不但于此,还包括 0x 开头的十六进制,XXeX类型的科学记数法 等等,如 '12e0'=='0x0C' 得到的是true。而在数值类型与字符串比较时,乃至一些数字开头的非数值串,比如 12=='12这个串' 得到的值也会是 true。
以是这些情形下,可能会使本来并不相同的字符串被剖断为相等。而利用===比较则为包含类型的比较,不会有任何转换,所以是可以准确比较字符串是否相同的。
其余吐槽一下JAVA,==居然比较不了字符串是否相等,由于字符串是一个工具,==变成了判断是否为同一个工具……
9、不能把switch中的case当作if来利用
在PHP函数switch……case中,switch 匹配的是case语句的值,而不能把case当if用。同时,switch表达式优先匹配与其值类型同等的case语句,类型不一致的放在后面处理,如下:
10、strrchr函数是查找某个字符,而不是查找字符串
在PHP手册上strrchr() 函数的阐明是查找字符串在另一个字符串中末了一次涌现的位置,并返回从该位置到字符串结尾的所有字符。如果成失落败,否则返回 false。实际上,这个函数是查找某个字符,而不是查找字符串。如下示例,很多人一开始肯定以为返回false,但实际上并不是。
上面示例解释,如果$b是字符串,只利用第一个字符,后面的其它字符会忽略。
本文由“编码之道”编辑整理,转载请注明出处。