神秘的.user.ini文件

.user.ini究竟是个神秘东东?

我们看看官方怎么说:
http://php.net/manual/zh/configuration.file.per-user.php
自 PHP 5.3.0 起,PHP 支持基于每个目录的 .htaccess 风格的 INI 文件。此类文件仅被 CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果使用 Apache,则用 .htaccess 文件有同样效果。
小白表示没看懂~
众所周知,php.ini是php的核心配置文件,在 PHP 启动时被读取,那么web目录的其他ini文件也是可以被php识别,官方还说了除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录 $_SERVER['DOCUMENT_ROOT'] 所指定的。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。

这样说的话,所有的配置都可以被.user.ini重新配置修改?噢,麦噶的
你想多了,官方还说了:
在 .user.ini 风格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI 设置可被识别。
小白,又举手了,什么是PHP INI* 模式呢?
官方是这样说的:
配置可被指定的范围「PHP: 配置可被设定范围 - Manual
这些模式决定着一个 PHP 的指令在何时何地,是否能够被设定。手册中的每个指令都有其所属的模式。例如有些指令可以在 PHP 脚本中用 ini_set() 来设定,而有些则只能在 php.ini 或 httpd.conf 中。
例如 output_buffering 指令是属于 PHP_INI_PERDIR,因而就不能用 ini_set() 来设定。但是 display_errors 指令是属于 PHP_INI_ALL 因而就可以在任何地方被设定,包括 ini_set()。
PHP INI* 模式的定义

PHP_INI_SYSTEM:可在 php.ini、httpd.conf 中设定
PHP_INI_PERDIR:可在 php.ini、httpd.conf、.htaccess 中设定
PHP_INI_USER:可在ini_set()、Windows注册表(PHP5.3起)、.user.ini中设定
PHP_INI_ALL:可在任何地方设定

也就是说只有PHP_INI_USER模式,才可以在 .user.ini 中设定,那么哪些配置可以在 .user.ini 中设定呢?
php.ini配置选项列表「PHP: php.ini 配置选项列表 - Manual
并不是所有的配置 .user.ini 都能修改,比如 disable_functions、upload_max_filesize
千年未解之谜,是不是在这里找到了答案?

[root@Tech1024]# rm -rf .user.ini 
rm: cannot remove '.user.ini': Operation not permitted

来看一下,该文件的属性

[root@Tech1024]# lsattr .user.ini 
----i--------e-- .user.ini

没错,文件被锁定了,不能修改,那么我们去除文件锁定属性

[root@Tech1024]# chattr -i .user.ini

是不是可以删除了,你是不是喜极而泣,啊,自己终于又行了。


在 Thinkphp、codeigniter、Laravel 等框架下,网站目录一般是在 public 下,但是 public 下的程序要跨目录调用 public 上级目录下的文件,因为 LNMP 默认是不允许跨目录访问的,所以都是必须要将防跨目录访问的设置去掉,有时候这些框架类的程序提示 500 错误也可能是这个问题引起的。
open_basedir restriction in effect 错误解决方法

chattr -i .user.ini # 解锁.user.ini文件
vim user.ini # 编辑 user.ini
# 只允许访问/home/wwwroot/xlboo.com/public目录(防跨目录)
open_basedir=/home/wwwroot/xlboo.com/public/ :/tmp/:/proc/
# 然后
chattr +i .user.ini # 加锁.user.ini文件
# 最后重启 PHP 或者 Nginx

open_basedir 介绍

open_basedir 将php所能打开的文件限制在指定的目录树中,包括文件本身。
当程序要使用例如 fopen() 或 file_get_contents() 打开一个文件时,这个文件的位置将会被检查。当文件在指定的目录树之外,程序将拒绝打开。
本指令不受安全模式打开或关闭的影响。
open_basedir 使用后 会影响 I/O 性能导致系统执行变慢
open_basedir 设置方法

  1. 在 php.ini 加入
open_basedir='指定目录'
  1. 在程序中使用
ini_set('open_basedir', '指定目录'); # 但不建议使用这种方法
  1. 在 apache 的 httpd.conf 中的 Directory 配置
php_admin_value open_basedir '指定目录'
  1. httpd.conf 中的 VritualHost
php_admin_value open_basedir "指定目录"
  1. nginx fastcgi.conf
fastcgi_param PHP_VALUE "open_basedir=指定目录"

用 open_basedir 指定的限制实际上是前缀,不是目录名。

open_basedir=/home/fdipzone # 不加/结尾, 限制为前缀
/home/fdipzone_abc # 也可以访问

如果要将访问限制为目录,请使用/结束路径名,例如:

open_basedir='/home/fdipzone/' # 加/结尾, 限制为目录

如果要设置多个目录,window 使用;分隔目录,linux 使用:分隔目录。

open_basedir=/www/;/tmp/;/proc/ # wondows
open_basedir=/www/:/tmp/:/proc/ # linux