令人困惑的是,该设置看起来像带有某些特殊语法的整数,但在内部定义为字符串。然后,只要更改值,该字符串就会被解析为单独的全局变量。至关重要的是,将字符串解析为整数的结果不会保存回设置表,因此,在调用时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