2011-05-23 52 views
5

我有一個web應用程序,將所有請求重定向到虛擬主機,然後根據URL決定哪些文件包含並運行。有一個Web服務通過POST接受大型XML文件。除了接受XML的服務外,我需要memory_limit和post_max_爲應用程序大約32M,這將需要它們的限制接近1024M。 ini_set('memory_limit','1024M')在腳本內工作,但不適用於post_max_size。如何設置更高的memory_limit,post_max_size和Apache/PHP中的特定腳本?

我似乎無法弄清楚如何去做。我試圖與此類似:

<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')); 

我會收到 串(3) 「32M」 字符串( 3)「30M」 串(3)「29M」

如果我訪問http://test.comhttp://test.com/services/big-service,但我想看看爲後來的URL較高的限制。

有沒有人有任何解決方案,這不會訴諸直接通過URL使用和訪問服務腳本?

回答

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是控制器

的克隆
<?php 
require_once('Controller.php'); 

會工作。

編輯:全虛擬主機塊:

<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> 
0

由於您在運行時決定客戶端正在尋找哪種Web服務,因此您僅限於可以執行的操作。你不能使用多個php.ini文件,因爲一旦PHP執行你的腳本,你就會被這個實例使用的.ini文件卡住。

在這種情況下,最好的選擇是在php.ini中設置較大的限制,然後在腳本中使用ini_set()指令來降低限制。如果這是不可接受的,那麼您可以做的最好的做法是隻將post_max_size設置爲較大的限制,然後在腳本中單獨設置每個其他限制。

問題是,當PHP開始執行腳本時,它已經從php.ini中讀取了它的post_max_size,並且數據已經被髮送到你的服務器,所以如果超過了這個限制,你的腳本就會獲得甚至不會被執行。

+0

是的,擁有大於memory_limit的post_max_size是一個問題,因爲當大帖子出現時它會致命(內存耗盡)。 – tandoan 2011-05-23 21:27:12

0

AFAIK php.ini是一個php實例(php5_module),您可以通過運行其中幾個解決您的問題 。

  1. 爲php5_module是每一個阿帕奇,一個解決辦法是運行 另一個Apache實例。問題是它無法在同一個端口上運行80

  2. 設置FCGI以解析php和php5_module。 這樣你可以給每個不同的啓動參數。您需要 將您的腳本重命名爲fph以外的.php文件才能解析(。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> 

不知道此設置如何防撞然而,嘿

0

你可以建立一個新的名稱基於虛擬主機(所以與其他DNS )處理相同的配置,並對內存限制進行一些更改。

這意味着您的應用程序的URL /服務/大服務應該始終使用此不同的DNS(和你的應用程序應檢查論文服務總是從右邊網址服用。

的php_value設置可以通過虛擬主機設置,所以它應該工作,如果你檢查this table你會看到memory_limit不在PERDIR範圍內,所以你不能只爲一個目錄設置它,而只能設置完整的VirtualHost.PERDIR範圍<Directory>可能已經能夠捕捉到的東西,而不是<Location>(但無論如何,你可能有一個mod_rewrite的主要index.php文件,所以它總是相同的目錄)

使用2 DNS解決方案時,您仍然遇到一個大問題,您可能會得到一些耗費1024M內存的apache進程,稍後它們將用於更簡單的請求,但仍會佔用此RAM。所以你必須經常清理你的apache兒童(例如MaxRequestPerChild爲100)。

即使使用php-fpm解決方案的Fcgid,如果沒有mod_php,您將使PHP腳本消耗大量內存,這不是最好的事情(您應該測試10%/30%/ 50%的客戶端請求正在使用這些服務,以及您的php內存使用情況如何被清理 - 或不)。您應該檢查Zend_Memory組件,它應該可用作具有Zend_Cache元素的庫組件,它將爲您管理'swapp內存以緩存',從而避免在大型服務中使用太多的RAM。

0

我懷疑這會工作。因爲,重定向總是到Controller.php,我不認爲Apache會支持基於位置的各種php.ini值。

如果/ services/big-service是一個目錄,那麼接受PHP的值是有意義的,我會建議你有一個共同的php.ini值或創建一個目錄並編寫一個.htaccess來擁有它自己的PHP設置。

相關問題