【发布时间】:2011-08-08 04:10:46
【问题描述】:
我为此工作了好几个小时,这让我发疯了!
所以我认为这是一个非常棘手的问题,因此需要详细的问题。
问题是:
我有一个服务器,可以接受通过 php 脚本上传的文件。
数据将分布到多张光盘上。
我想在上传过程中将文件保存到正确的光盘(tmp 文件)。
因为:
文件需要稍后移动,我不希望它花费很长时间(从系统 tmp 目录复制到目标磁盘)
系统盘是一个ssd,在上面写入和删除这么多数据时不会很开心。
此服务器配置更改了初始值。在上传过程中,可以看到临时文件并查看其文件大小如何增加:
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;
}
我只是硬编码 42。如果它有效,我会从 THE_REQUEST 解析正确的值。它不起作用。脚本是 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"
所以很明显这个“常数”在这个范围内是不可用的
现在我的想法已经用完了
我必须管理我的方法确实是反复试验。
任何人都可以指出正确的方向或告诉我这是不可能的并证明这一点?
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 容器...它很丑陋,我希望避免这一步并拥有一个通用的网络服务器配置,但它似乎是唯一的方法 - 至少它可以工作。
我仍然想知道是否有更好的方法,我认为深入研究网络服务器配置非常有趣。 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 可以为我指明正确的方向,那就太好了。
【问题讨论】:
-
你想要不同的上传目录有什么理由吗? PHP 已经为临时文件分配了一个随机名称,因此两个或多个上传不太可能相互踩踏。至于 Apache 变量,这些变量仅适用于专门寻找/期望它们的某些领域。 php_value/php_admin_value 不是其中之一。
-
在这种情况下,不同的目录是不同的物理硬盘。我在问题中说明了原因(没有多余的文件复制)。事实上,上传不是不太可能,但不可能通过他们的名字来收集(假设你没有一个共享的网络挂载作为多个服务器的临时目录或其他东西)。
-
明白了。我唯一能想到的就是为每个磁盘设置一个虚拟主机,并使用重写规则在上传时重新路由上传。然后您可以在每个虚拟主机中硬编码 tmp 路径,而无需使用变量。除非您以极快的速度添加磁盘或者它们的名称经常更改,否则它可能就足够了。
-
是的,我也在考虑这个问题。问题是根据我目前的设计,每个服务器上的位置不是 1-n,而是整个云中的每个磁盘都有自己的 id,因此它们可以变得非常大,我必须为每台服务器配置虚拟主机,它需要很多维护。我希望为所有服务器提供一个通用配置,但方法是有道理的,需要多考虑一下。也许我可以改变我的数据库布局来区分磁盘。
-
对于大规模虚拟主机,请查看 mod_macro,您将能够使用“使用 MyVHOSt 42.somwhere.com dir42”等简单命令编写所有 VH
标签: php apache .htaccess configuration initialization