Cookieに設定できる文字列の上限について

PHP

Cookieに設定できる文字列の上限について調べました。

環境

 ブラウザ Windows Edge
 プログラム PHP 8.3.6 (cli) on ubuntu

確認したいこと

 ①Cookieに設定できる文字列に上限があるのか
 ②マルチバイトを使用した場合の上限

実験方法

 次のプログラムを使用して、どこまで行けるのか実験しました

//"A"を10バイト分つなげる
$str = str_repeat("A", 10);
echo $str . "<br>";
echo strlen($str).  "<br>";
setcookie($cookie_name,$str,$expiry_time,$path,$domain,$secure,$httponly );
echo "<hr>";
var_dump($_COOKIE);

実行すると次の結果が得られます。

str_repeatの値を順に増やしていく方法でエラーになったところが限界です。

実験結果①

10 問題なし
1000 問題なし
10000 エラー
 [Wed Sep 11 21:02:49.939327 2024] [php:warn] [pid 8237] [client 192.168.19.1:53886] PHP Warning:  Cannot modify header information - headers already sent by (output started at /var/www/html/api/cookie_set.php:15) in /var/www/html/api/cookie_set.php on line 18

 10000バイトの文字を入力したところ、エラーメッセージが出ました。
 エラーメッセージを確認したところ、
  setcookie()より前にecho等でHTMLの生成が始まっている
というエラーメッセージとのこと。
 プログラムを修正して再チャレンジします。

//"A"を10バイト分つなげる
$str = str_repeat("A", 10);
setcookie($cookie_name,$str,$expiry_time,$path,$domain,$secure,$httponly );
echo $str . "<br>";
echo strlen($str).  "<br>";
echo "<hr>";
var_dump($_COOKIE);

このコードを使用すると、10000を超えてもエラーは発生しませんが、値がcookieの値が更新されなくなりました。

10000 更新されない
2000 更新される
5000 更新されない
3000 更新される
4000 更新される
4500 更新されない
4100 更新されない
4050 更新される
4099 更新されない
4080 更新される
4090 更新されない
4085 更新される
4089 更新されない
4087 更新される
4088 更新される
4089 更新されない 再確認

ということで、
   4088バイトまで登録することができる
ことがわかりました。(こういう何でもない作業好きです…)

実験結果②

次はマルチバイトを使用した場合の上限について確認していきます。

プログラムは先ほどとほぼ同じです。

//"あ"を10バイト分つなげる
$str = str_repeat("あ", 10);
setcookie($cookie_name,$str,$expiry_time,$path,$domain,$secure,$httponly );
echo $str . "<br>";
echo strlen($str).  "<br>";
echo "<hr>";
var_dump($_COOKIE);

実行結果は次の通りです。

日本語1文字で3バイトですので、UTF-8を使っているようです。
1361文字(4083バイト)まで登録できるはず!
 確認したところ、次のような結果になりました。

1361(4083バイト) 更新されず
100(300バイト) 更新される
1000(3000バイト) 更新されず
500(1500バイト) 更新されず
300(900バイト) 更新される
400(1200バイト) 更新される
450(1350バイト) 更新される
480(1440バイト) 更新されず
470(1410バイト) 更新されず
460(1380バイト) 更新されず
455(1365バイト) 更新されず
451(1353バイト) 更新される
453(1359バイト) 更新される
454(1362バイト) 更新される
455(1365バイト) 更新されず 確認

ということで、日本語は
   454文字 まで登録することができる
ことがわかりました。
 計算(4088/9=454.22)から、一文字9バイト使っているという計算になるので
   URLエンコード(“あ”) →  ”%E3%81%82″
から、1文字が9バイトとなるURLエンコード後の値を格納していると思われます。

 試しに、”=” を使って実験したところ、1362文字まで登録できました。
   URLエンコード(“=”) →  ”%3D”
で3バイトとなり、
   4088/3=1362.66
ですので、URLエンコード後の値で間違いなさそうです。

まとめ

 ①Cookieに設定できる文字列に上限があるのか
  半角英数字”A”だと 4088 文字入力可能
 ②マルチバイトを使用した場合の上限
  日本語の ”あ” だと 454文字入力可能

ということがわかりました。
 エラーが起きないので、値がちゃんと設定されているかは確認しないとわかりません。
 大量の文字列をcookieに保存するときは、注意した方がよさそうです。(通常はこんなに入れないと思いますが…)