PHP 是否对 php.ini 文件进行任何解析?
Does PHP do any parsing on the php.ini file?
运行 PHP RHEL 7.7 下的版本 7.1.30。
我想增加 memory_limit,但不确定我的语法是否正确(即 256M 或 256MB)。因此,首先我将一个错误的值 "Hugo" 作为 memory_limit 设置。问题在于 phpinfo()(httpd 下的 运行)字面意思是字符串 "Hugo",即:
所以这让我有点担心 PHP 实际上并没有对值进行任何健全性检查。 (如果提供的值不好,我希望它恢复为默认值,例如)
任何人都可以对此发表评论 - 特别是,您如何知道 PHP 是否会执行某些操作(如果可以提供任意字符串)。
首先,
我们首先需要了解PHP.ini在口译工作流程中是如何工作的。
memory_limit 是 PHP 的指令。
当与 PHP 函数一起使用时,你必须做这样的事情 ini_set(‘memory_limit’,’256MB’)
。因此,此函数会暂时将您的值设置为解释器变量。如果你看得更近一些,那么你可以得到两列,一列用于本地,一列用于全局。分别体现了价值观对个人的能力。
但是,当你定义为全局时,你需要分别设置一个后缀为K,M,G。如果我们使用 apache .htaccess 超过此值,则 PHP fpm 需要相同的值。
这里令人困惑的是,该设置看起来像一个具有某些特殊语法的整数,但在内部定义为一个字符串。每当值发生变化时,该字符串就会被解析为一个 separate 全局变量。至关重要的是,将字符串解析为整数的结果不会保存回设置 table,因此当您调用 phpinfo()
时,您看到的是原始输入,而不是解析后的值。
你可以在源码中看到这个:
- The setting is defined with a callback for when it is changed
- The callback is fed the raw string value
- The callback for that particular setting parses the string to an integer using a function called
zend_atol
,处理特殊后缀
- 然后调用 a function which sets a global variable(“AG”的意思是“分配管理器全局变量”,如果在其中编译,宏用于管理线程安全)
支持的语法最终在zend_atol
中定义,其中:
- 解析字符串以获得数值,忽略任何其他文本
- 查看字符串的最后一个字符,如果是
g
、G
、m
、M
、[=18=,则乘以前面的值],或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
运行 PHP RHEL 7.7 下的版本 7.1.30。
我想增加 memory_limit,但不确定我的语法是否正确(即 256M 或 256MB)。因此,首先我将一个错误的值 "Hugo" 作为 memory_limit 设置。问题在于 phpinfo()(httpd 下的 运行)字面意思是字符串 "Hugo",即:
所以这让我有点担心 PHP 实际上并没有对值进行任何健全性检查。 (如果提供的值不好,我希望它恢复为默认值,例如)
任何人都可以对此发表评论 - 特别是,您如何知道 PHP 是否会执行某些操作(如果可以提供任意字符串)。
首先, 我们首先需要了解PHP.ini在口译工作流程中是如何工作的。 memory_limit 是 PHP 的指令。
当与 PHP 函数一起使用时,你必须做这样的事情 ini_set(‘memory_limit’,’256MB’)
。因此,此函数会暂时将您的值设置为解释器变量。如果你看得更近一些,那么你可以得到两列,一列用于本地,一列用于全局。分别体现了价值观对个人的能力。
但是,当你定义为全局时,你需要分别设置一个后缀为K,M,G。如果我们使用 apache .htaccess 超过此值,则 PHP fpm 需要相同的值。
这里令人困惑的是,该设置看起来像一个具有某些特殊语法的整数,但在内部定义为一个字符串。每当值发生变化时,该字符串就会被解析为一个 separate 全局变量。至关重要的是,将字符串解析为整数的结果不会保存回设置 table,因此当您调用 phpinfo()
时,您看到的是原始输入,而不是解析后的值。
你可以在源码中看到这个:
- The setting is defined with a callback for when it is changed
- The callback is fed the raw string value
- The callback for that particular setting parses the string to an integer using a function called
zend_atol
,处理特殊后缀 - 然后调用 a function which sets a global variable(“AG”的意思是“分配管理器全局变量”,如果在其中编译,宏用于管理线程安全)
支持的语法最终在zend_atol
中定义,其中:
- 解析字符串以获得数值,忽略任何其他文本
- 查看字符串的最后一个字符,如果是
g
、G
、m
、M
、[=18=,则乘以前面的值],或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