<?php
setcookie("TestCookie", $value, PHP_INT_MAX);
などと書くと、64bit環境で
PHP Warning: Expiry date cannot have a year greater than 9999 in hoge.php
などというエラーが出る。32bit環境だとPHP_INT_MAXは西暦2038年だが、64bit環境だと西暦3000億年だからだろう。PHPにはありがちなことだが、そのような機能制限についてドキュメントは存在しない。
http://php.net/manual/ja/function.setcookie.php
(もっとも、PHPがこれを通したとしても、ブラウザ側が適切に扱えないという事はありそうなので、PHPだけを責めるわけにもいかないが)
2038年問題を避けようとした結果がごらんの有様だよ!
具体的にどういう動作になるのかとか、正確にはいくつまでOKなのかは調べていない。エラーメッセージを素直に信じるなら、西暦9999年12月31日23時59分59秒が上限だろう。
果てしなくどうでもいい問題だが、踏んだので記念パピコ。
追記:
setcookieの実装はここ(エラーメッセージの定義もここ)
https://github.com/php/php-src/blob/94e15ff3877f842e5eb5c89e3aeab214fb4a3a33/ext/standard/head.c#L76
日付のフォーマット関数が呼ばれて
https://github.com/php/php-src/blob/19e8052be31d8361477906932f4c6dc9cd738de2/ext/date/php_date.c#L1219
フォーマット関数で
https://github.com/php/php-src/blob/94e15ff3877f842e5eb5c89e3aeab214fb4a3a33/ext/date/lib/unixtime2tm.c#L40
while (tmp_days >= DAYS_PER_LYEAR) {
cur_year++;
if (timelib_is_leap(cur_year)) {
tmp_days -= DAYS_PER_LYEAR;
} else {
tmp_days -= DAYS_PER_YEAR;
}
}
となるので、ここで3000億年分ループを回して関数が呼ばれるため、たいていの環境で処理がタイムアウトする。また、9999を超えるとエラー扱いになるため(最初のコード)、クッキーは吐かれない。
(タイムスタンプをいじりながら確認すると、処理時間が線形で伸びていくのがわかる)
なお、9999年までは正常に吐けることを確認(PHP 5.3.9 64bit)。