10、filesize缓存的问题

PHP的filesize居然会缓存(当然还有不少,这里仅用filesize举例,其它会缓存的函数,以官方文档为准)
线上代码经常随机出各种问题,排查了1个月,线上加各种日志,最终发现是filesize缓存的问题,如下代码:

  1. echo filesize("a.txt");
  2. exec("rm a.txt");  // 删除文件
  3. echo filesize("a.txt"); // 这里会输出大小,而不是报错说文件不存在
  4. echo filesize("b.txt");
  5. echo filesize("a.txt"); // 这里会报错文件不存在,因为只缓存最后一个文件,缓存里只有b,没有a的缓存了

看到了吧,filesize不仅有缓存,而且还只缓存最后一个文件,所以说PHP的开发人员也不知道怎么考虑的,就不会加个filesize_withcache方法?
知道了原因,解决也就简单了,在filesize调用前清除缓存,加代码: clearstatcache()
参考官方文档:http://php.net/manual/zh/function.filesize.php

9、保存源码文件时,注意要使用utf-8无bom签名

之前用Windows的记事本编辑文件,发布到Linux上线后,一直报错:Cannot modify header information - headers already sent by (output started at xxx.php:1)
用Winmerge或BeyondCompare对比代码也无法发现问题,后来用Netbeans才发现文件最前面多了一个不可见字符,研究后才知道是Windows的Bom签名
也就是说,在Windows上开发,在Linux上发布,注意要使用不支持Bom的编辑器,如果用VisualStudio要选择高级保存选项里的不带签名

 

1、null和空、0、false等四个值的比较

在PHP中,== 会先进行类型转换,再进行对比,而===会先比较类型,如果类型不同直接返回不相等,参考如下示例

  1. $a = null; $b = ''; $c = 0; $d = false;
  2. echo ($a == $b)?1:0;    // 输出1
  3. echo ($a === $b)?1:0;   // 输出0
  4. echo ($a == $c)?1:0;    // 输出1
  5. echo ($a === $c)?1:0;   // 输出0
  6. echo ($b == $c)?1:0;    // 输出1
  7. echo ($b === $c)?1:0;   // 输出0
  8. echo ($a == $d)?1:0;    // 输出1
  9. echo ($a === $d)?1:0;   // 输出0

对于我这种以前只写js或C#代码的码农,被这几个值忽悠过n次,n大于3

2、strrchr函数

W3School站点上的注释如下:

strrchr() 函数查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符。
如果成失败,否则返回 false。

实际上,这个函数是查找某个字符,而不是查找字符串,应该参考官方文档

代码示例:

  1. $a = 'abcdef.txt';
  2. $b = '.php';
  3. echo strrchr($a, $b);

上面的代码输出是:.txt

也就是说,如果$b是字符串,只使用第一个字符,后面的其它字符会忽略

注:php提供了strstr函数,为什么不提供strrstr函数呢,虽然自己实现也很简单

3、foreach里的引用赋值参见官方文档

这个引用赋值很好哇,对用C#的我,在C#里要修改foreach的元素,是不可能的,是会出异常滴,php把这个变成了可能,但是:
在官方文档里有一句警告:Warning 数组最后一个元素的 $value 引用在 foreach 循环之后仍会保留。建议使用 unset() 来将其销毁。
我们看一组代码:

  1. $a = [1,2,3];
  2. foreach($a as &$item){
  3. echo $item . ',';
  4. }
  5. //unset($item); // 引用赋值后不销毁对象
  6. foreach($a as $item){
  7. echo $item . ',';
  8. }

上面的代码的输出如下:
1,2,3,1,2,2  看最后一个输出的是2,而不是3,就是因为代码里没有销毁$item造成的,原因如下:
第一个循环,把3的引用赋给了$item,第二个循环,把1赋给了$item,因为$item是引用,导致数组的元素3变成了1,明白了吗?

4、isset与empty的联系和区别isset文档 empty文档
empty对如下8种情况返回true:
  null、 空串""、字符串0"0"、空array、布尔值false、数字0、浮点数0.0、类里用var定义但是未赋值

isset 检测变量是否设置,并且不是 NULL,但是对于empty的8种情况,只有null返回false,其它7种情况都返回true

综上所述,除了empty描述的的非null的7种情况,在其它情况下, if(empty(变量)) 等效于 if(!isset(变量))

灵活用法一则:直接访问 $arr['aaa'] 可能报错,说aaa不存在,可以用:
if(isset($arr['aaa']){ 操作代码} 或 if(!empty($arr['aaa']){ 操作代码}

5、trim函数遇到中文空格时,会乱码

  1. $str = '  《前后有全半角空格》  ';
  2. var_dump($str);
  3. $str2 = trim($str, '  ');
  4. var_dump($str2);
  5. $str3 = mb_ereg_replace('^(?:\s| )+|(?:\s| )+$', '', $str);
  6. var_dump($str3);
  7. $str4 = mb_ereg_replace('^[\s ]+|[\s ]+$', '', $str);
  8. var_dump($str4);

参考如上的代码,输出结果:

  1. string '  《前后有全半角空格》  ' (length=38)
  2. string '�前后有全半角空格》' (length=28)
  3. string '《前后有全半角空格》' (length=30)
  4. A PHP Error was encountered
  5. Severity: Warning
  6. Message: mb_ereg_replace(): mbregex compile err: invalid code point value

可以看出:trim导致乱码出现了,正则^(?:\s| )+|(?:\s| )+$ 可以正常工作,而正则^[\s ]+|[\s ]+$却编译异常,原因我还没搜索到

6、intval在Windows和Centos上,最大值范围不同
在centos上,intval转换的最大值是9223372036854775807,

而在我的Win7x64+64位的php上,转换最大值却是2147483647,非常奇怪,手册明明说64位系统都是9223372036854775807,
这么大一坑啊,官方解释php6以下在win上仅是测试版,不支持64位

7、MySQL字段类型为varchar时,不能用where xx=123来检索,会无法利用索引
建议所有SQL的值都用单引号括起来,如:where xx='123',如果字段类型为int,也能正确利用索引

8、执行SQL后不判断返回值,或判断逻辑错误:

$sql = 'insert into app_log(id)  select 0 from dual where 1=2';
$this->db->query($sql);
return true; // 不加判断,直接返回true

$sql = 'insert into app_log(id)  select 0 from dual where 1=2';
$result = $this->db->query($sql);
if ($result) { // 有bug,插入不成功,result也是true
    return true;
}
return false;

上面的2段代码应该改成:

$sql = 'insert into app_log(id)  select 0 from dual where 1=2';
$this->db->query($sql);
// 如果sql有语法问题,affected_rows是-1
if ($this->db->affected_rows() > 0) {
    return true;
}
return false;

注意:mysql中,update a set name='123' where id=1;
如果id为1的记录,name已经是123,那么这条update语句的affected_rows()=0

原文链接:http://blog.csdn.net/youbl/article/details/41014367

php常见的坑的更多相关文章

  1. Golang开发者常见的坑

    Golang开发者常见的坑 目录 [−] 初级 开大括号不能放在单独的一行 未使用的变量 未使用的Imports 简式的变量声明仅可以在函数内部使用 使用简式声明重复声明变量 偶然的变量隐藏Accid ...

  2. 纯Socket(BIO)长链接编程的常见的坑和填坑套路

    本文章纯属个人经验总结,伪代码也是写文章的时候顺便白板编码的,可能有逻辑问题,请帮忙指正,谢谢. Internet(全球互联网)是无数台机器基于TCP/IP协议族相互通信产生的.TCP/IP协议族分了 ...

  3. 学习笔记之C/C++指针使用常见的坑

    https://mp.weixin.qq.com/s/kEHQjmhNtSmV3MgHzw6YeQ 避免内存泄露 不再用到的内存没有释放,就叫做内存泄露 在C/C++中,通过动态内存分配函数(如mal ...

  4. 详讲H5、WebApp项目中常见的坑以及注意事项

    首先我们中会有一些常用的meta标签,如下: <!--防止手机中网页放大和缩小--> <meta name="viewport" content="wi ...

  5. Android中常见的坑有哪些?

    对于安卓开发入门级程序猿而言,由于不熟悉代码.工具等等,掉进一些坑中是难免的,今天小编在网上看到一位大神总结的Android开发中比较常见的坑及其原因和解决办法,赶脚还不错,分享出来,给大家提个醒. ...

  6. Android使用WebView开发常见的坑

    原文链接:http://mp.weixin.qq.com/s?__biz=MzAwODE1NTI2MQ==&tempkey=uP3a%2BOgIN7vPbLfJp3BTCl2KabYi1%2F ...

  7. Go语言常见的坑

    目录 1. 可变参数是空接口类型 2. 数组是值传递 3.map遍历是顺序不固定 4. 返回值被屏蔽 5.recover必须在defer函数中运行 6. main函数提前退出 7.通过Sleep来回避 ...

  8. 【常见踩坑】USB调试安装失败(Installation failed with message INSTALL_CANCELED_BY_USER)

    一.写在前面 最近一直在忙活着项目重构,忙活了一个多月(那是天天加班,不分昼夜呀,ps:这不是我司要求的哈),终于把沉积了三四年的老项目给重构了,目前在测试阶段,也总算有了点闲时来跟大家分享分享一些问 ...

  9. Mybatis通过注解方式实现批量插入数据库 及 常见的坑

    原文地址:http://f0rb.iteye.com/blog/1207384 MyBatis中通过xml文件配置数据库批量操作的文章很多,比如这篇http://www.cnblogs.com/xcc ...

  10. Spring,SpringMvc配置常见的坑,注解的使用注意事项,applicationContext.xml和spring.mvc.xml配置注意事项,spring中的事务失效,事务不回滚原因

    1.Spring中的applicationContext.xml配置错误导致的异常 异常信息: org.apache.ibatis.binding.BindingException: Invalid ...

随机推荐

  1. 【Android】3.14 公交线路查询功能

    分类:C#.Android.VS2015.百度地图应用: 创建日期:2016-02-04 一.简介 利用BusLineSearch方法可查询公交线路的详情信息. 二.运行截图 简介:介绍查询公交线路功 ...

  2. SQL游标操作每隔5分钟时间段数据统计信息

    Tb_People 表信息: id     uname    era     amount    plushtime           1000031    张亮    中年    100000   ...

  3. 57. 3Sum【medium】

    Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...

  4. WEB开发的标准目录结构

    刚才在书上看到的,感觉很重要,简单做个笔记 把你的jsp.css.js代码分别放到3个文件夹中(这3个文件夹就名为jsp,css,js),文件夹中设置子目录,这些子目录最好命名与html文件的子目录命 ...

  5. Linux模块的加载和卸载

    Linux操作系统中模块操作相关命令解释lsmod  查看已经安装好的模块, 也可以查看/proc/modules文件的内容. 实际上,lsmod读命令就是通过查看/proc/modules的内容来显 ...

  6. 面试-Hash是怎么实现的?

    相关资料:http://blog.csdn.net/luyuncsd123/article/details/11590861 Hash生命起源:那么,我们开始思考:有什么方式既能够具备数组的快速查询的 ...

  7. 【C#】Config配置文件的读写,及无法写入/保存配置文件的问题

    目的: 一些数据为了在项目打包好后也能方便的修改和调用,通常会把这些数据放到配置文件中,避免硬编码,修改配置文件内容更方便,而不用修改源代码. 使用: 在解决方案资源管理器中找到App.config文 ...

  8. c#利用反射Assembly 对类和成员属性进行操作

    protected static void test() { //获取程序集 Assembly assembly = System.Reflection.Assembly.GetExecutingAs ...

  9. GB2312汉字区位码、交换码和机内码转换方法 (ZT)

    GB2312汉字区位码.交换码和机内码转换方法 (ZT) 为了适应计算机处理汉字信息的需要,1981年我国颁布了GB2312国家标准.该标准选出6763个常用汉字(其中,一级常用汉字3755个,二级汉 ...

  10. Android——RadioGroup和CheckBox

    xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= ...