我在一些系统上遇到过,当尝试设置在 php.ini 中的每个主机设置中设置的设置时,ini_set() 会失败并返回 false。注意这一点。
(PHP 4, PHP 5, PHP 7, PHP 8)
ini_set — 设置配置选项的值
设置给定配置选项的值。配置选项将在脚本执行期间保留此新值,并在脚本结束时恢复。
成功时返回旧值,false
失败时。
示例 #1 设置 ini 选项
<?php
echo ini_get('display_errors');
if (!ini_get('display_errors')) {
ini_set('display_errors', '1');
}
echo ini_get('display_errors');
?>
[[[编辑者注:是的,这是非常真实的。对于
register_globals、magic_quotes_gpc 和其他。
]]]
许多设置,虽然它们确实被设置了,但对你的脚本没有任何影响...... 比如 upload_max_filesize 会被设置,但上传的文件在设置被更改之前就已经传递到你的 PHP 脚本了。
还有其他由 ini_set() 设置的设置,由于这个原因可能太迟了(post_max_size 等)。
注意,尝试通过 php.ini 或 .htaccess 设置。
当检查 ini_set() 的成功时,请记住它将返回成功时的旧值 - 这可能为“0”。因此,你不能仅仅比较返回值 - 你必须检查“身份”。
<?php
// 这将无法确定 ini_set() 的成功,而是
// 它只测试旧值是否等于 false
if ( !ini_set( 'display_errors', '1' ) )
throw new \Exception( 'Unable to set display_errors.' );
// 这是确定成功的正确方法
if ( ini_set( 'display_errors', '1' ) === false )
throw new \Exception( 'Unable to set display_errors.' );
?>
这解释了报告的 ini_set() “始终” 似乎失败的情况!
在设置 output_handler 时要小心,因为你无法使用 ini_set() 来更改它。*叹息*
在我的 php.ini 中,我有这个用于我的网页(并且我想要它)
output_handler = ob_gzhandler
但这会导致我的命令行脚本在最后之前不显示输出。
#!/usr/bin/php -q
<?php
ini_set('output_handler', 'mb_output_handler');
echo "\noutput_handler => " . ini_get('output_handler') . "\n";
?>
root@# ./myscript.php
output_handler => ob_gzhandler
显然(根据 Richard Lynch)
> 太晚了!
> ob_start() 在此时已经启动。
> ob_flush() 直到没有更多缓冲区。
如果它不是你的服务器,因此你想隐藏你会话变量中的数据以防止其他用户访问,将你的脚本中的 session.save_handler 设置为共享内存非常有用,方法是
<?php ini_set('session.save_handler','mm'); ?>
记住:你必须在每个使用会话变量的脚本中设置它,在“session_start()”之前,否则 php 找不到它们。
当你的 ISP 不允许你添加默认包含目录时 - 扩展 'include_path' 变量可能很有用
<?php ini_set('include_path',ini_get('include_path').':../includes:'); ?>
在 .htaccess 文件中使用 'php_flag' 设置 PHP_INI_PERDIR 设置,如下所示
php_flag register_globals off
php_flag magic_quotes_gpc on
小心 - 在某些情况下,当通过 ini_set 将 zlib.output_compression 设置为“On”时,PHP 不会发送 Content-type 标头,浏览器会混淆输出。改为将其设置为所需的缓冲区大小,这样会发送正确的标头
<?php
ini_set("zlib.output_compression", 4096);
?>
为了更改 zend.assertions 或 assert.exception 值,请尝试使用 ini_set() 函数,但请注意它可能会失败。
示例
<?php
$ret = @ini_set('zend.assertions', '1');
if ($ret === false) echo 'ini_set() failed before line ', __LINE__, PHP_EOL;
虽然这不属于手册内容,但对于在该页面上寻找 zend_optimizer.* ini 选项的人来说,它可能很有用,这些选项通常被安装。
有关 "zend_optimizer.optimization_level" 和 "zend_optimizer.enable_loader" 选项的信息,请访问
http://www.zend.com/support/user_docs/ZendOptimizer/PDF/ZendOptimizer_UserGuide.pdf
如果你收到类似以下的通用错误:
Maximum execution time of 30 seconds exceeded
如果你设置了 ini_set(max_execution_time, 300);
你的问题将得到解决
请注意 300 表示 300 秒,即 5 分钟,你可以设置其他值!
[[[编辑注意:仅仅因为你能设置某样东西
并不意味着它会按预期工作。这取决于
设置。例如,设置 register_globals 在
运行时将毫无用处,因为它的工作已经
在它到达你的脚本之前就完成了。
]]]
当某个设置无法在用户脚本中更改时,ini_set 的返回值将是 "empty",而不是你可能期望的 "false"。
如果你在脚本中检查返回值是否是 "false",脚本将继续处理,尽管设置没有被设置。
布尔返回值用于可以在脚本中更改的设置。否则,将返回空值。
要测试这两个错误条件,请使用
<?php
if (empty($blnResult) or (!$blnResult)) {
echo "setting cannot be set";
exit;
}
?>
我弄明白了为什么 php 不会输出错误,比如代码中的预期分号 ';',并输出 500 错误。某些服务器配置为使用指令 display_errors=Off; 在页面上省略 php 错误。
在大多数情况下,服务器会输出 500 内部服务器错误,而不是 php 错误,因为使用了该指令。
为了防止这种情况,你必须直接在 php.ini 文件中设置该指令,服务器将正确地显示 php 错误。在运行时设置 ini_set('display_errors', true) 不会起作用。
如果你使用 gz_handler,你可能想要切换到
zlib.output_compression
这可以通过 ini_set 控制进行控制。
<?php ini_set('zlib.output_compression', 'Off'); ?>
或者
<?php ini_set('zlib.output_compression', 'On'); ?>
要从 .htaccess 文件更改设置,还需要 Apache 中配置的目录权限允许此操作。
httpd.conf 中的 <Directory /foo/bar> 条目必须包含 "AllowOverride All" 或至少 "AllowOverride Options",才能从 .htaccess 文件读取 PHP 设置。
例如,在 Fedora Core 2 中,/var/www/html/ 的默认设置为 "AllowOverride None",因此通过 .htaccess 更改安装在 /var/www/html/ 下的应用程序的 PHP 设置将不起作用。
要查找 Apache php 设置,请尝试以下操作。
> cd /etc/apache2
> grep -r -n -i safe_mode_exec_dir *.conf
或者
> grep -r -n -i safe_mode.*On *.conf
如果你找到了一个生成的配置文件,显然你需要找到它的源模板,并在那里更改所需的内容。
我刚刚浪费了一个阳光明媚的星期天,寻找 safe_mode_exec_dir 在哪里被更改。
是的,phpinfo 中的 Local Value 确实意味着 "在 php.ini 文件和此处之间被更改",就像你想的那样。
如果你有一个自动化的虚拟主机配置,比如 confixx,php ini 值可能会分布在许多文件中。
它们可以在 Apache 配置文件中更改,这些文件可以有任何名称,但通常以 .conf 结尾,此外还在 .htaccess 文件中。
如果你在 httpd.conf 中使用 php_admin_value 设置了某个东西,那么在运行时就无法设置它的值,即使它不是 PHP_INI_SYSTEM。
对于服务器管理员来说,这是一个有趣的信息,这可能有助于禁用某些东西的设置... 比如 allow_url_fopen。
- Davey
虽然大多数布尔设置可以通过传递 '0'、'Off' 或 `No'(实际上任何不是 '1'、'On' 或 'Yes' 的东西 - 不区分大小写)给 ini_set() 来禁用,但需要注意的是,ini_get() 会返回设置的字面字符串。因此,如果你稍后要通过调用 ini_get() 检查此设置,并且它被设置为 'Off'(一个非空字符串,它评估为 True),那么你将不得不通过 (区分大小写) 字符串比较来专门检查它,而不是更简单的
if (ini_get('config_setting')) { /* ... */ }
因此,如果你需要禁用布尔设置,我认为最好将它们设置为 '0'(它简单地评估为 False)。