最近在写一个项目界面。测试的时候发现在服务器上测试的正常功能在本地一直有问题。经过一步步排查,最终锁定的问题是函数strtotime返回了一个false值,导致数据无法插入数据库。个人博文地址:http://www.weiya.me/item/61.html同样的代码运行起来不一样,原因是环境不一致。要么PHP版本不同,要么位数不同。我的电脑是64位的。这里PHP位数不一致,服务器用的是64位,我本地是32位的。而strtotime传入的是一个字符串2050-1-123:59:59,大于2038-1-1903:14:07,所以在32位PHP下直接返回false,而64位PHP则不会受影响的影响。Y2K38漏洞导致上述问题的根本原因是Y2K38漏洞,又称UnixMillenniumBug。32位系统或PHP该漏洞会影响PHP等所有32位系统下使用UNIX时间戳整数记录时间的编程语言。整型变量可以保存的最大时间是2038年1月19日03:14:07,过了这个时间整型值就会溢出。64位系统或PHP64位系统下可保存的最远日期是当前宇宙年龄的21倍——292亿年。所以不会受到这个漏洞的影响。如何检测如何知道您的系统是否受此漏洞影响。很简单,直接使用strtotime将大于2038年1月19日03:14:07的日期进行转换。或者使用date函数将大于2147454847的时间戳转换为日期。让我们演示方法一echodate("Y-m-dH:i:s",2556115199);如果上面的结果返回2050-12-3123:59:59,那么就没有问题。如果它返回1914-11-2509:31:43那么它就会受到影响。方法二var_dump(strtotime("2050-12-3123:59:59"));如果上面的结果返回2556115199,那么就正常了。如果它返回false那么它也会受到影响。解决方案1??替换系统和PHP都是64位的。这个成本比较高,但是可以一劳永逸的解决问题。解决方案2PHP5.2之后,提供了一个函数DateTime,暂时解决了这个问题。//1.将日期字符串转换为时间戳$obj=newDateTime("2050-12-3123:59:59");echo$obj->format("U");//2556115199//2.时间戳转换为日期字符串$obj=newDateTime("@2556115199");//这里在时间戳前必须??写一个@符号$timezone=timezone_open('Asia/HONG_KONG');//设置时区$obj->setTimezone($timezone);echo$obj->format("Y-m-dH:i:s");//2050-12-3123:59:59//DateTime也可以有其他方式$obj=newDateTime("2050-12-3123:59:59");echo$obj->format("Y/m/dH:i:s");//换种方式输入时间字符串2050/12/3123:59:59通过DateTime类操作日期不会受到Y2K38漏洞的影响,可以支持到9999年12月31日
