¿PHP hace algún análisis en el archivo php.ini?

24

Ejecutando PHP Versión 7.1.30 bajo RHEL 7.7.

Estoy deseando aumentar memory_limit, pero no estaba seguro de tener la sintaxis correcta (es decir, 256M o 256MB). Entonces, para empezar, puse un mal valor "Hugo" como la configuración de memory_limit. El problema con esto es el resultado de que phpinfo () (ejecutado bajo httpd) literalmente tiene la cadena "Hugo" en su lugar, es decir:

ingrese la descripción de la imagen aquí

Entonces, esto me tiene un tanto preocupado de que PHP en realidad no haga ninguna comprobación de cordura para los valores. (Si el valor proporcionado era malo, esperaría que volviera a un valor predeterminado, por ejemplo)

¿Alguien puede comentar sobre esto? En particular, ¿cómo saber si PHP hará cumplir las cosas (si se puede proporcionar una cadena arbitraria)?

Patrick Rynhart
fuente
44
Excelente pregunta
Tink
3
De esto: php.net/manual/en/faq.using.php#faq.using.shorthandbytes Supongo que es lo mismo que (int) 'HUGO'; // => 0. Que comienza a fallar en mi máquina con 2 MB de memoria utilizada.
Yoshi
Para el registro, la sintaxis correcta esmemory_limit 256M .
Tigger
@Yoshi Creo que deberías publicar tu respuesta. Es una buena explicación
Maksym Fedorov
@MaksymFedorov dudo, ya que no tengo una referencia real para mi suposición. Por ahora es solo una observación.
Yoshi

Respuestas:

19

Lo confuso aquí es que la configuración parece un número entero con alguna sintaxis especial, pero se define internamente como una cadena. La cadena se analiza luego en una variable global separada cada vez que se cambia el valor. Crucialmente, el resultado de analizar la cadena a un entero no se guarda de nuevo en la tabla de configuración, por lo que cuando llama phpinfo(), ve la entrada original, no el valor analizado.

Puedes ver esto en la fuente:

La sintaxis compatible se define en última instancia en zend_atol, que:

  1. analiza la cadena para un valor numérico, ignorando cualquier texto adicional
  2. mira el último carácter de la cadena, y se multiplica el valor anterior si se trata de g, G, m, M, k, oK

Un valor sin dígitos al inicio se analizará como cero. Al configurar la variable global, esto establecerá el límite de memoria al mínimo permitido, en función de la constante ZEND_MM_CHUNK_SIZE.

Puede ver el efecto configurando el límite de memoria, luego ejecutando un bucle que asigna rápidamente una gran cantidad de memoria y viendo lo que sale en el mensaje de error. Por ejemplo:

# Invalid string; sets to compiled minimum
php -r 'ini_set("memory_limit", "HUGO"); while(true) $a[]=$a;'
# -> PHP Fatal error:  Allowed memory size of 2097152 bytes exhausted

# Number followed by a string; takes the number
php -r 'ini_set("memory_limit", "4000000 HUGO"); while(true) $a[]=$a;'
# -> PHP Fatal error:  Allowed memory size of 4000000 bytes exhausted

# Number followed by a string, but ending in one of the recognised suffixes
# This finds both the number and the suffix, so is equivalent to "4M", i.e. 4MiB
php -r 'ini_set("memory_limit", "4 HUGO M"); while(true) $a[]=$a;'
# -> PHP Fatal error:  Allowed memory size of 4194304 bytes exhausted
IMSoP
fuente
Gracias @IMSoP por esa gran evaluación. ¿Se debe informar este tipo de cosas en cualquier tipo de bugtracker? Encuentro la respuesta que phpinfo () genera altamente contra-intuitiva. Y algunos resultados de depuración de lo que hace php cuando encuentra valores inesperados tampoco irían mal.
Tink
1
@tink Supongo que podría plantear una solicitud de función en bugs.php.net , o enviar un mensaje a la lista de correo Internals, que es donde ocurre la mayor parte de la coordinación. Encontré una solicitud similar de hace varios años , pero no parece haber tenido ninguna respuesta.
IMSoP
Gracias de nuevo, lo investigaré! :)
tink
0

Lo primero es lo primero, primero tenemos que entender cómo funciona PHP.ini en la forma de flujo de trabajo de interpretación. memory_limit es directivas para PHP.

cuando se usa con la función PHP, debe hacer algo como esto ini_set(‘memory_limit’,’256MB’). Por lo tanto, esta función establecerá temporalmente su valor en la variable intérprete. Si ve más de cerca, puede obtener las dos columnas Una es para Local y otra para global. Eso muestra la capacidad de los valores para el individuo respectivamente.

Pero, cuando definió global, debe establecerlo como un sufijo con K, M, G, respectivamente. Si excedemos este valor usando apache .htaccess, se requiere lo mismo para PHP fpm.

Pranav Bhatt
fuente
3
Me gustaría señalar amablemente que el OP no pregunta cómo establecer el límite de memoria :)
Karolis