2011-05-23 28 views
5

Tengo una aplicación web que redirige todas las solicitudes al host virtual a un controlador, que luego decide qué archivos incluir y ejecutar en función de la URL. Hay un servicio web que acepta archivos XML grandes a través de POST. Necesito el memory_limit y post_max_ para ser ~ 32M para la aplicación, excepto para el servicio que acepta el XML, que necesitará que sus límites estén más cerca de 1024M. ini_set('memory_limit','1024M') funciona dentro del script, pero no funcionará para el post_max_size.¿Cómo establecer un memory_limit, post_max_size, y para un script específico en Apache/PHP?

Parece que no puedo entender cómo hacerlo. Estaba tratando algo similar a esto:

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

tanto, con la configuración anterior, si controller.php parece

<?php 
echo '<pre>'; 
var_dump(ini_get('memory_limit')); 
var_dump(ini_get('post_max_size')); 
var_dump(ini_get('upload_max_filesize')); 

voy a recibir cadena (3) "32M" cadena (3) "30M" cadena (3) "29M"

si volviese a http://test.com y http://test.com/services/big-service, pero me gustaría ver a los límites más altos para las direcciones URL posteriores.

¿Alguien tiene alguna solución para esto que no recurra a usar y acceder al script del servicio directamente a través de la URL?

Respuesta

1

El problema es que mod_rewrite hace que siempre vaya a /Controller.php, por lo que nunca se utiliza el bloque de ubicación con los servicios. El uso de mod_rewrite normas adicionales

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] 

y luego tener ControllerBig ser un clon de controlador

<?php 
require_once('Controller.php'); 

va a funcionar.

Editar: El bloqueo total 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> 
0

Dado que en el tiempo de ejecución está decidiendo qué servicio web está buscando el cliente, está limitado a lo que puede hacer. No puede usar múltiples archivos php.ini, porque una vez que PHP está ejecutando su script, está atascado con el archivo .ini que utilizó esa instancia.

La mejor apuesta en este caso es establecer los límites más grandes en php.ini, y luego usar las directivas ini_set() en sus scripts para bajar ese límite. Si eso no es aceptable, lo mejor que puede hacer es establecer solo post_max_size en el límite más grande, y luego establecer cada uno de sus otros límites de forma individual en su secuencia de comandos.

El problema es que cuando PHP comienza a ejecutar su script, ya ha leído su post_max_size desde php.ini, y los datos ya han sido enviados a su servidor, por lo que si este límite se ha excedido, su script ganó incluso se ejecutará.

+0

Sí, tener un post_max_size mayor que memory_limit es un problema, ya que aparecerá Fatal Out (memoria agotada) cuando pase una publicación grande. – tandoan

0

AFAIK php.ini es uno por instancia php (php5_module), puede solucionar su problema ejecutando varios de ellos.

  1. como php5_module es uno por Apache, uno soluciones sería correr otro ejemplo Apache. El problema es que no se puede ejecutar en el mismo puerto 80

  2. configuración FCGI para analizar php junto con php5_module. de esta manera puede dar diferentes parámetros de inicio para cada uno. necesitaría para cambiar el nombre de sus scripts a algo que no sea .php para fcgi para analizar (.fcgi tal vez)

muestra

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> 

No sabe cómo a prueba de errores esta configuración es, sin embargo, je

0

Se puede configurar un host virtual basado en nombre nuevo (por lo que con otro DNS) manejando la misma configuración, con algunos cambios en el límite de memoria.

Esto significa que sus direcciones URL de aplicaciones para/servicios/gran servicio siempre deben usar este DNS diferente (y su aplicación debe comprobar tesis servicios son siempre tomados de la URL correcta.

Los ajustes php_value pueden ajustarse por medio VirtualHost , por lo que debería funcionar. Si marca this table verá que Memory_limit no está en el alcance PERDIR, por lo que no puede establecerlo solo para un Directorio, solo el VirtualHost completo. Con un alcance PERDIR, un <Directory> pudo haber captado el cosa en lugar de <Location> (pero de todos modos puede tener un mod_rewrite para el archivo index.php principal, por lo que siempre es el mismo directorio).

Con la solución de 2 DNS, usted todavía tiene un gran problema, puede obtener que parte de su proceso de apache consuma 1024M de RAM, y luego serán utilizados para solicitudes más simples, pero aún así tome esta RAM. Por lo tanto, tendría que limpiar a menudo sus hijos Apache (MaxRequestPerChild a 100, por ejemplo).

Incluso con la solución Fcgid de php-fpm, así que sin mod_php, harás que tu script PHP consuma mucha RAM y esto no es lo mejor que puedes hacer (debes probar lo que sucede con tu RAM cuando 10%/30%/50% de las solicitudes de los clientes están usando estos servicios, y cómo su uso de la memoria RAM php es limpieza - o no). Debe verificar el componente Zend_Memory, también debe poder usarse como un componente de biblioteca con elementos Zend_Cache, administrará una memoria swapp 'para almacenar en caché', evitando usar demasiado RAM en su gran servicio.

0

dudo que esto funcionará. Desde entonces, la redirección siempre va a Controller.php y no creo que Apache pueda tener varios valores de php.ini basados ​​en la ubicación.

Si/services/big-service es un directorio, entonces tiene sentido aceptar los valores para el PHP, le sugiero que tenga un valor php.ini común o cree un directorio y escriba un .htaccess para tener su propio Configuración de php.

Cuestiones relacionadas