如何设置更高的memory_limit,post_max_size,以及Apache / PHP中的特定脚本?

时间:2011-05-23 17:32:36

标签: php apache memory

我有一个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.comhttp://test.com/services/big-service,但我希望看到后续网址的上限。

是否有人对此有任何解决方案,而不是直接通过URL使用和访问服务脚本?

5 个答案:

答案 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)一个,你可以解决你的问题 通过运行其中几个。

  1. 因为php5_module是每个apache一个,所以一个解决方案就是运行 另一个Apache实例。问题是它不能在同一个端口80中运行

  2. 设置FCGI以解析php和php5_module。 这样你就可以为每个人提供不同的启动参数。你需要的 将脚本重命名为.php以外的其他内容,以便fcgi解析(可能是.fcgi)

  3. 样品

    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设置。