在apache2中动态设置upload_tmp_dir

时间:2011-04-18 20:08:17

标签: php apache .htaccess configuration initialization

我正在研究这个问题几个小时,它让我疯狂!

所以我认为这是一个非常艰难的问题因此。

问题是:

  • 我有一台服务器通过php脚本接受上传文件。

  • 数据将分发到多张光盘。

  • 我想在上传期间将文件保存到右侧光盘(tmp文件)。

因为:

  • 该文件需要稍后移动,我不希望它花费很长时间(从系统tmp目录复制到目标磁盘)

  • 系统驱动器是一个ssd,如果在其上写入和删除如此多的数据,它将不会非常高兴。

此服务器配置更改init值。在上传期间,可以查看临时文件并查看其文件大小的增加情况:

Alias /thundercloud /home/thundercloud
<Directory /home/thundercloud>
    php_admin_value upload_tmp_dir /home/thundercloud/locations/42/tmp
</Directory>

我的标签位于 / home / thundercloud 中, / home / thundercloud / locations (以数字1-n命名)中有几个符号链接,均指向相应的挂载点。

现在我需要的是获得数字42(这是第42号磁盘 - 服务器中只有14个磁盘,而不是仅供测试)是动态的。

我对请求有很多控制权,所以我基本上不关心它是由主机名,变量,子目录等决定的。

所以我的第一次尝试是这样的:

RewriteLock /var/lock/apache2/rewrite.lock
Alias /thundercloud /home/thundercloud
RewriteMap getuplaodlocation prg:/home/thundercloud/uploadloc.php
RewriteEngine On
<Directory /home/thundercloud>
    AllowOverride All
    php_admin_value upload_tmp_dir ${getuplaodlocation:%{THE_REQUEST}}
</Directory>

相应的重写地图是:

#!/usr/bin/php
<?
set_time_limit(0); # forever program!
$keyboard = fopen("php://stdin","r");
while (1) {
    $line = trim(fgets($keyboard)); // dont care for now
    echo '/home/thundercloud/locations/42/tmp'.PHP_EOL;
}

我jut hardcoded 42.如果它工作,我会从THE_REQUEST解析正确的falue。那没起效。脚本是chmod 777和一切。

我的下一次尝试是:

Alias /thundercloud /home/thundercloud
<Directory /home/thundercloud>
    SetEnvIfNoCase Host lionel\.2x\.to upload=/home/thundercloud/locations/42/tmp
    php_admin_value upload_tmp_dir upload
</Directory>

没有运气。

所以我最后的尝试是:

Alias /thundercloud /home/thundercloud
<Directory /home/thundercloud>
    php_admin_value upload_tmp_dir /home/thundercloud/locations/%{REMOTE_HOST}/tmp
</Directory>

也没有运气。我打印了ini_get_all()并获得了以下输出:

["upload_tmp_dir"]=>
  array(3) {
    ["global_value"]=>
    string(47) "/home/thundercloud/locations/%{REMOTE_HOST}/tmp"

所以显然这个“常量”在这个范围内不可用

现在我用完了想法

我必须管理我的apporaches真的是反复试验。

任何人都可以指出我正确的方向或告诉我它不可能并证明这一点吗?

ps:它显然在php运行时无效;)

编辑:

好了几个小时后,Marc B发表了一篇有用的评论,我提出了这个“解决方案”:

<VirtualHost *:80>
    ServerName 42.thundercloud.lionel.2x.to
    DocumentRoot /home/thundercloud
    php_admin_value upload_tmp_dir /home/thundercloud/locations/42/tmp
</VirtualHost>
<VirtualHost *:80>
    ServerName 43.thundercloud.lionel.2x.to
    DocumentRoot /home/thundercloud
    php_admin_value upload_tmp_dir /home/thundercloud/locations/43/tmp
</VirtualHost>

只是强行为每个磁盘强制一个自己的VirtualHost容器......它很丑陋,我希望避免这一步并拥有一个通用的webserver配置,但它似乎是唯一的方法 - 至少它有效。

我仍然想知道是否有更好的方式,我觉得非常有趣的是如此深入到网络服务器配置。 Apache非常灵活,当你把它推到极限时它变得非常有趣(至少我认为是这样)。

这就是为什么我会把这个问题保持开放并给它一个赏金。

编辑:

经过一些研究后,我认为可能有一个解决方案应用这里的技术: http://httpd.apache.org/docs/2.0/vhosts/mass.html

类似的东西:

<VirtualHost *> 
Use CanonicalName off
VirtualDocumentRoot /home/thundercloud/locations/%0/tmp/
php_admin_value open_basedir VIRTUAL_DOCUMENT_ROOT
<VirtualHost>

这只是一个想法,尚未经过测试。还是想弄清楚。在这种情况下,路径不正确,但可能存在符号链接的解决方法。如果some1可以指出我正确的方向,那就太好了。

2 个答案:

答案 0 :(得分:3)

php_admin_value设置中无法使用变量替换。这只是因为apache模块只能解析自己的config指令。 mod_rewrite支持使用环境变量,因为这样做是内置于mod_rewrite本身。

由于您无法使用变量,因此您必须使用<Location>之类的内容设置所有可能的值。例如:

RewriteEngine on
RewriteRule /upload(\d+)$       /upload.php

php_admin_value upload_tmp_dir /tmp

<Location /upload1>
    php_admin_value upload_tmp_dir /tmp/1
</Location>
<Location /upload2>
    php_admin_value upload_tmp_dir /tmp/2
</Location>
....
<Location /upload100>
    php_admin_value upload_tmp_dir /tmp/100
</Location>

然后您只需发布到/upload{$id}。这显然不像可能的替代那样动态。有两种明显的替代方案可以使它更整洁:

1)有一个单独的构建脚本,它生成一个文件放在/etc/httpd/conf.d中,每个服务器都有相关的行

2)创建一个通用配置文件,该文件只有例如100个位置规则。在每台服务器上,您只需要设置所需的符号链接,并让生成表单的PHP决定指向上传的卷 - 您最终会得到一堆/uploadX个网址无法在每台服务器上运行,但无论如何都不会发布任何内容。

另一种方法是使用mod_macro,它基本上允许你做同样的事情,但使用较小的配置文件,自动生成扩展配置,但实质上只是生成一个包含大量vhost /位置块的大配置文件。要像你原来要求的那样做得很好,你需要修改mod_php。

答案 1 :(得分:-1)

如果我正确理解了这个问题,你可以随时使用ini_set

ini_set ("upload_tmp_dir", "/home/thundercloud/locations/42/tmp");