我有一个Web应用程序,可以将对虚拟主机的所有请求重定向到控制器,然后控制器根据URL决定要包含和运行的文件。有一个Web服务通过POST接受大型XML文件。对于应用程序,我需要memory_limit和post_max_为~32M,但接受XML的服务除外,这需要它们的限制接近1024M。 ini_set('memory_limit','1024M')
在脚本中有效,但不适用于post_max_size。
我似乎无法弄明白该怎么做。我正在尝试类似的东西:
<VirtualHost *:80>
ServerName test.com
DocumentRoot /var/www/test.com/html
php_admin_value include_path .:/var/www/test.com/includes:/var/www/test.com/includes/libs
php_value session.use_only_cookie 1
<Location />
php_value memory_limit 32M
php_value post_max_size 30M
php_value upload_max_filesize 29M
</Location>
<Location /services/big-service>
php_value memory_limit 1024M
php_value post_max_size 128M
</Location>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/(.*)$
RewriteCond %{REQUEST_URI} !^/(.*)(html|gif|jpg|png|ico|css|js|dtd|swf|flv|xml)$
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^/(.*)$ /Controller.php/$1 [PT]
</VirtualHost>
因此,使用上面的配置,如果Controller.php看起来像
<?php
echo '<pre>';
var_dump(ini_get('memory_limit'));
var_dump(ini_get('post_max_size'));
var_dump(ini_get('upload_max_filesize'));
我会收到的 string(3)“32M” string(3)“30M” string(3)“29M”
如果我访问http://test.com和http://test.com/services/big-service,但我希望看到后续网址的上限。
是否有人对此有任何解决方案,而不是直接通过URL使用和访问服务脚本?
答案 0 :(得分:1)
问题是mod_rewrite导致它总是转到/Controller.php,所以从不使用带有服务的Location块。使用其他mod_rewrite规则
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/services/(.*)$
RewriteCond %{REQUEST_URI} !^/(.*)(html|gif|jpg|png|ico|css|js|dtd|swf|flv|xml)$
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^/(.*)$ /ControllerBig.php/services/$1 [PT]
然后让ControllerBig成为Controller的克隆
<?php
require_once('Controller.php');
会奏效。
编辑:完整的VirtualHost区块:
<VirtualHost *:80>
ServerName test.com
DocumentRoot /var/www/test.com/html
php_admin_value include_path .:/var/www/test.com/includes:/var/www/test.com/includes/libs
php_value session.use_only_cookie 1
<Location />
php_value memory_limit 32M
php_value post_max_size 30M
php_value upload_max_filesize 29M
</Location>
<Location /services/big-service>
php_value memory_limit 1024M
php_value post_max_size 128M
</Location>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/services/(.*)$
RewriteCond %{REQUEST_URI} !^/(.*)(html|gif|jpg|png|ico|css|js|dtd|swf|flv|xml)$
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^/(.*)$ /ControllerBig.php/services/$1 [PT]
RewriteCond %{REQUEST_URI} ^/(.*)$
RewriteCond %{REQUEST_URI} !^/(.*)(html|gif|jpg|png|ico|css|js|dtd|swf|flv|xml)$
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^/(.*)$ /Controller.php/$1 [PT]
</VirtualHost>
答案 1 :(得分:0)
由于您在运行时决定客户端正在寻找哪种Web服务,因此您只能使用自己可以执行的操作。你不能使用多个php.ini文件,因为一旦PHP执行你的脚本,你就会被实例使用的.ini文件所困。
在这种情况下,最好的办法是在php.ini中设置较大的限制,然后在脚本中使用ini_set()指令来降低该限制。如果这是不可接受的,那么您可以做的最好的事情就是将post_max_size设置为更大的限制,然后在脚本中单独设置其他每个限制。
问题是,当PHP开始执行你的脚本时,它已经从php.ini读取了它的post_max_size,并且数据已经被POST到你的服务器,所以如果超过了这个限制,你的脚本就赢了“甚至被执行。
答案 2 :(得分:0)
AFAIK php.ini是每个php实例(php5_module)一个,你可以解决你的问题 通过运行其中几个。
因为php5_module是每个apache一个,所以一个解决方案就是运行 另一个Apache实例。问题是它不能在同一个端口80中运行
设置FCGI以解析php和php5_module。 这样你就可以为每个人提供不同的启动参数。你需要的 将脚本重命名为.php以外的其他内容,以便fcgi解析(可能是.fcgi)
样品
LoadModule fcgid_module modules/mod_fcgid.so
LoadModule php5_module c:/apps/php/php5apache2_2.dll
AddHandler application/x-httpd-php .php
PHPIniDir "C:/apps/php/ini1"
<IfModule mod_fcgid.c>
AddHandler fcgid-script .fcgi
FcgidInitialEnv PHPRC "c:/apps/php/ini2"
FcgidWrapper "c:/apps/php/php-cgi.exe" .fcgi
AddType application/x-httpd-fcgi .fcgi
</IfModule>
然而,不确定这种设置是如何防撞的,呵呵
答案 3 :(得分:0)
您可以设置一个新的基于名称的虚拟主机(因此使用另一个 DNS )处理相同的配置,并对内存限制进行一些更改。
这意味着/ services / big-service的应用程序URL应该始终使用这个不同的DNS(并且您的应用程序应该检查这些服务总是来自正确的URL。
php_value设置可以由VirtualHost设置,因此它应该可以工作。如果您检查this table,您将看到memory_limit不在PERDIR范围内,因此您不能仅为目录设置它,只能为完整的VirtualHost设置它。使用PERDIR范围,<Directory>
可能已经能够捕获事物而不是<Location>
(但无论如何,您可能有一个mod_rewrite到主index.php文件,因此它始终是相同的目录)。 / p>
使用2 DNS解决方案你仍然有一个大问题,你可能会得到一些apache进程消耗1024M的RAM,它们稍后将用于更简单的请求,但仍然需要这个RAM。所以你必须经常清理你的apache孩子(例如MaxRequestPerChild到100)。
即使使用php-fpm解决方案的Fcgid,所以如果没有mod_php,你将使你的PHP脚本消耗大量的RAM,这不是最好的事情(你应该测试你的RAM发生在10%/ 30%/ 50%的客户端请求正在使用这些服务,以及您的php RAM使用情况如何清理 - 或不清除。您应该检查Zend_Memory组件,它应该可以用作具有Zend_Cache元素的库组件,它将为您管理'swapp内存以缓存',避免使用太多RAM在您的大型服务中。
答案 4 :(得分:0)
我怀疑这会奏效。因为,重定向总是转到Controller.php,我不认为Apache会支持基于Location的各种php.ini值。
如果/ services / big-service是一个目录,那么接受PHP的值是有意义的,我建议你有一个常见的php.ini值或创建一个目录并写一个.htaccess来拥有它自己的php设置。