注意:这也适合超级用户。
我正在使用 apache2 mpm itk 和 open_basedir 在共享主机上设置 PHP 5.3.10,每个用户可能看不到或更改另一个用户的文件。在 apache2 vhost 设置中,我添加了适当的条目来限制用户:
AssignUserId userA userA
php_admin_value open_basedir /home/userA/www/
php_admin_value upload_tmp_dir /home/userA/www/tmp/
php_admin_value session.save_path /home/userA/www/tmp/
SetEnv TMPDIR /home/userA/www/tmp/
现在,第一行设置用于 apache2 的 linux 用户,接下来的三行定义 basedir、上传目录和会话保存路径在用户目录中。稍后我会回到最后一行。
现在解决问题:sys_get_temp_dir()
应该还给 php 的临时目录,在 linux 系统上默认为 /tmp。出于安全原因,此目录应位于 userA 的 open_basedir 中。根据5.3.10的php-source,sys_get_temp_dir()
-function使用环境变量TMPDIR得到这个目录:
// php-src/main/php_open_temporary_file.c:217-219
/* On Unix use the (usual) TMPDIR environment variable. */
{
char* s = getenv("TMPDIR");
这是上面配置中的第五行应该做的。但是,sys_get_temp_dir()
只需返回全局系统目录,忽略环境变量(在 $_SERVER 中完美设置,也可以通过 查看phpinfo()
)。
这会导致依赖于的各种软件出现一些令人讨厌的错误sys_get_temp_dir()
,因为该目录不在open_basedir
设置范围内。我尝试将变量直接设置为 $_ENV 和 $_SERVER 而不改变行为。我试过putenv('TMPDIR=/home/userA/www/tmp')
没有变化。
但是,我可以通过将变量定义为 /etc/apache2/envvars 来更改输出 - 这对我来说没用,因为我希望每个 VHOST 都有自己的临时文件夹。
到目前为止,我发现的唯一解决方案是通过runkitsys_get_temp_dir()
之类的扩展覆盖内部,并通过auto_prepend_file强制包含它。但是那个解决方案太脏了,我简直不敢相信,周围没有更好的解决方案。
所以,我的问题:有没有办法改变sys_get_temp_dir()
在 apache2 vhost 设置中设置的结果,而不用 runkit 重新实现函数?
编辑: apache 版本是 2.2.22,我目前使用 mod_php。因为我必须手动添加所有用户,所以 fcgi 或类似的设置也是可能的。