ここで混乱するのは、設定が特別な構文を持つ整数のように見えますが、内部的に文字列として定義されていることです。次に、値が変更されるたびに、文字列が個別のグローバル変数に解析されます。重要なことに、文字列を整数に解析した結果は設定テーブルに保存されないため、を呼び出すとphpinfo()
、解析された値ではなく、元の入力が表示されます。
これはソースで見ることができます:
サポートされる構文は、最終的にで定義されますzend_atol
。
- 追加のテキストを無視して、文字列を数値で解析します
- 文字列の最後の文字を見て、乗算前の値それがある場合は
g
、G
、m
、M
、k
、またはK
先頭に数字がない値は、ゼロとして解析されます。グローバル変数を設定するとき、これは定数に基づいて、メモリ制限を許容される最小値に設定しますZEND_MM_CHUNK_SIZE
。
メモリ制限を設定し、大量のメモリをすばやく割り当てるループを実行して、エラーメッセージで何が出力されるかを確認することで、効果を確認できます。例えば:
# Invalid string; sets to compiled minimum
php -r 'ini_set("memory_limit", "HUGO"); while(true) $a[]=$a;'
# -> PHP Fatal error: Allowed memory size of 2097152 bytes exhausted
# Number followed by a string; takes the number
php -r 'ini_set("memory_limit", "4000000 HUGO"); while(true) $a[]=$a;'
# -> PHP Fatal error: Allowed memory size of 4000000 bytes exhausted
# Number followed by a string, but ending in one of the recognised suffixes
# This finds both the number and the suffix, so is equivalent to "4M", i.e. 4MiB
php -r 'ini_set("memory_limit", "4 HUGO M"); while(true) $a[]=$a;'
# -> PHP Fatal error: Allowed memory size of 4194304 bytes exhausted