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

作者:Craig Buckler
原文链接:http://www.sitepoint.com/blogs/2010/08/24/is-your-php-application-affected-by-the-y2k38-bug/

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

1
2
3
4
5
6
<?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 的类 (5.1 中开始实验加入,5.3 版本中扩展了一些方法)…

1
2
3
4
5
6
<?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 类来规划新的解决方案了。

你在开发中碰到过 Y2K38 问题吗?是如何解决的?欢迎一起来分享你的经验。

[翻译:avenger]

posted @ 2012-06-24 20:00  永哥  阅读(871)  评论(0)    收藏  举报