注意PHP的下一个千年虫:Y2K38

标签: , ,

我不想危言耸听,先在你的环境下试试如下代码的运行结果吧:

<?php
$date = '2040-02-01';
$format = 'l d F Y H:i';
$mydate1 = strtotime($date);
echo '<p>', date($format, $mydate1), '</p>';
?> 

如果一切正常的话,你会看到如下输出"Wednesday 1 February 2040 00:00″。如果你看到了一个60年代到70年代之间的日期,那说明你的PHP应用存在一个叫Y2K38的安全漏洞!

Y2K38漏洞是什么?

Y2K38,又称Unix Millennium Bug,这个漏洞将会影响到所有32位系统下用UNIX时间戳整数来记录时间的PHP,及其它编程语言。一个整型的变量所能保存的最大时间为2038年1月19日03:14:07。超过这个时间后,整型数值将会溢出。从1970年01月01日开始,到世界标准时2038年01月19日星期二凌晨03:14:07超过2^31–1。2^31–1就是0x7FFFFFFF,相信很多编程员都看过,在32位系统里,这表示最大的有符号整数。如果用它来表示秒数,大概相当于68.1年,从1970年到2038年刚好是这个数。

是的,这是28年以后的事情了。你们肯定有些人认为我是在忋人忧天。要知道世纪末的千年虫问题就是这样产生的。另外,我们在开发一些应用的时候,可能会用到未来的日期,比如一个25年期的长期存款,退休金和保险业的财务数据等。

64 位系统会受到影响吗?

理论上不会,如果你是在64位的操作系统下使用PHP,你的程序应该不会受到影响。我强烈建议你进行一下测试。64位系统下可以保存的日期最远日期是现在宇宙年龄的21倍——292亿年。

如果你确认你的财务系统运行在64位系统上的话,你可以安稳的睡个大头觉了。

有其它的解决方法吗?

幸运的是,PHP从5.2版本开始引入了一个DateTime的类

<?php
$date = '2040-02-01';
$format = 'l j F Y H:i';
$mydate2 = new DateTime($date);
echo '<p>', $mydate2->format($format), '</p>';
?>

如上所示,通过DateTime类来操作日期不会受到Y2K38漏洞的影响,可以最远支持到9999 年12月31日。

你可能不需要马上在你的应用里解决这个问题,不过在你做下一个项目的时候,或者应该考虑下用DateTime类来规划新的解决方案了。

原文地址:http://phpe.net/2010/09/is-your-php-application-affected-by-the-y2k38-bug/

随机文章:

  1. 用VBS获取图片分辨率
  2. VBS过程和函数参数传递的方式默认是ByVal还是ByRef?
  3. VB6拾遗:内联汇编与CallWindowProc函数
  4. 注意PHP的下一个千年虫:Y2K38
  5. JavaScript 记忆(Memoization)

4 条评论 发表在“注意PHP的下一个千年虫:Y2K38”上

  1. welkin说道:

    额~
    我记得DZ升级后发帖会有1970或者注册日期变成1970年
    不知道和这个有关没

  2. 孤舟蓑翁说道:

    刚测试了一下,我的php应用还真存在千年虫问题

留下回复