Situación actual: PHP2Shell. Dos vulnerabilidades críticas de PHP (CVSS 9.2) permiten ejecutar código malicioso sin autenticación. Parches desde el 21/10/2026.Qué hacer ahora →

El php.ini explicado: estructura, niveles y prioridad

Dónde encuentra PHP sus ajustes, en qué orden se aplican y quién puede sobrescribirlos. Base de cualquier refuerzo y de las medidas provisionales frente a PHP2Shell.

Actualizado 5 min de lecturaConocimiento de PHP

En resumen: el php.ini es el archivo de configuración central de PHP. PHP lo lee al iniciar: una vez en los módulos de servidor y en cada invocación en CGI y CLI. A ello se suman archivos adicionales de un directorio de escaneo, ajustes en el pool de FPM o en Apache, .htaccess o .user.ini, y ini_set() en el código. Qué nivel puede modificar un valor lo determina su modo de modificación, por ejemplo INI_SYSTEM o INI_PERDIR. Los valores fijados con php_admin_value ya no puede sobrescribirlos la aplicación.

¿Qué es el php.ini?

El php.ini es un archivo de texto con entradas del tipo name = wert. Determina cómo se comporta PHP: cuánta memoria puede usar un script, si los errores aparecen en el navegador, cómo funcionan las sesiones y qué extensiones se cargan. Los comentarios empiezan con un punto y coma.

Según el manual de PHP, el archivo se lee al iniciar PHP. En los módulos de servidor como mod_php esto ocurre solo una vez, al iniciar el servidor web; en CGI y CLI, en cada invocación. PHP-FPM lee su configuración al iniciar y al recargar el servicio. Por eso, un cambio sin reinicio o recarga normalmente no surte efecto.

Desde PHP 8.3, según el manual, una entrada puede remitir a una variable de entorno con un valor de sustitución:

memory_limit = ${PHP_MEMORY_LIMIT}
max_execution_time = ${PHP_MAX_EXECUTION_TIME:-30}

¿Dónde busca PHP el php.ini?

El manual describe un orden fijo. Primero cuenta una ruta fijada expresamente, por ejemplo PHPIniDir en Apache o la opción -c en CGI y CLI. Si no, PHP construye una ruta de búsqueda con:

  1. la variable de entorno PHPRC,
  2. en Windows, la entrada del registro IniFilePath,
  3. el directorio de trabajo actual, salvo en las SAPI que lo desactivan, como la CLI,
  4. el directorio del binario de PHP o del módulo,
  5. la ruta fijada al compilar con --with-config-file-path.

En esta ruta de búsqueda, PHP busca primero un archivo php-SAPI.ini, por ejemplo php-cli.ini, y solo después php.ini. A continuación, PHP lee en orden alfabético todos los archivos .ini del directorio de escaneo, fijado mediante PHP_INI_SCAN_DIR o, al compilar, mediante --with-config-file-scan-dir. Qué archivos se han cargado lo muestran php --ini o la función php_ini_scanned_files().

php --ini
php -r 'var_dump(php_ini_loaded_file(), php_ini_scanned_files());'

Ambos comandos muestran el estado de la línea de comandos. Para el sitio web puede aplicarse otro archivo, porque cada SAPI puede tener su propia configuración; más información en SAPI explicada.

Modos de modificación: ¿quién puede fijar qué valor?

No todo ajuste puede fijarse en cualquier lugar. El manual asigna a cada directiva un modo de modificación:

Modo Dónde puede fijarse el valor
INI_USER en scripts con ini_set(), en el registro de Windows y en .user.ini
INI_PERDIR en php.ini, .htaccess, httpd.conf o .user.ini
INI_SYSTEM solo en php.ini o httpd.conf
INI_ALL en cualquier lugar

Ejemplos del manual: memory_limit tiene el modo INI_ALL y el valor por defecto 128M; post_max_size tiene INI_PERDIR y el valor por defecto 8M; upload_max_filesize tiene INI_PERDIR y el valor por defecto 2M. expose_php solo puede figurar en el php.ini.

Según el manual, los archivos .user.ini solo los leen las SAPI de CGI y FastCGI, es decir, también PHP-FPM. PHP los busca desde el directorio del script hacia arriba hasta el Document Root y, por defecto, los vuelve a leer como máximo cada 300 segundos (user_ini.cache_ttl). En mod_php, .htaccess asume este papel.

¿Qué valor se aplica al final? Los niveles por prioridad

De forma simplificada: cuanto más tarde actúa un nivel, más probable es que su valor prevalezca, siempre que el modo de modificación lo permita.

  1. php.ini de la SAPI correspondiente
  2. Archivos adicionales del directorio de escaneo, en orden alfabético
  3. Configuración del servidor: pool de FPM con php_value o php_admin_value, VirtualHost de Apache
  4. Nivel de directorio: .htaccess en mod_php, .user.ini en FPM y CGI
  5. Tiempo de ejecución: ini_set() en el código de la aplicación

La excepción es decisiva: según el manual, los valores fijados con php_admin_value o php_admin_flag no pueden sobrescribirse con ini_set(). Así, los administradores bloquean frente a la aplicación los ajustes relevantes para la seguridad. Se describe con detalle en php_admin_value: bloquear ajustes frente a la sobrescritura.

El php.ini tras PHP2Shell: qué ha cambiado

Las medidas provisionales de php.net frente a PHP2Shell son casi todas ajustes INI: memory_limit=-1 bloqueado frente a la sobrescritura, post_max_size limitado, session.upload_progress.enabled=0 y, en PHP 8.5, fatal_error_backtraces=0. php.net subraya que session.upload_progress.enabled no debe fijarse mediante ini_set() ni .user.ini, sino en php.ini, en el pool de FPM o en la configuración del servidor, con el posterior reinicio de todos los workers. La lista completa está en Medidas inmediatas si aún no puede parchear.

Con las versiones corregidas 8.5.12, 8.4.27, 8.3.36 y 8.2.35, según el manual, también ha cambiado memory_limit: ahora es un límite blando. El nuevo ajuste memory_hard_limit_percent fija un límite duro. Sin un valor propio equivale al doble de memory_limit y, si supera 1G, al valor más 1G. Si se supera, el proceso termina de inmediato con estado de salida 137. Cómo elegir ambos límites de forma razonable lo explica Fijar memory_limit correctamente.

Consejo

Según el manual: si una versión de PHP no reconoce memory_hard_limit_percent, está afectada por CVE-2026-109618 y CVE-2026-109619. En las distribuciones con backports, el changelog del paquete demuestra además el estado.

¿Cómo ayuda PHP SOS en concreto?

  • Averiguar los valores efectivos: leemos para cada SAPI qué archivos se cargan y qué valor se aplica al final.
  • Ordenar los niveles: eliminamos entradas contradictorias de paneles, pools, .htaccess y .user.ini.
  • Establecer bloqueos: en el marco del refuerzo del servidor fijamos mediante php_admin_value los valores relevantes para la seguridad.
  • Documentar: documentamos los ajustes y el reinicio para que el estado pueda demostrarse más adelante.

Preguntas frecuentes

¿Dónde está el php.ini?

Depende del sistema operativo, del paquete y de la SAPI. En Debian y Ubuntu hay carpetas propias para cada versión y SAPI, por ejemplo /etc/php/8.3/fpm/php.ini y /etc/php/8.3/cli/php.ini. En la línea de comandos, php --ini muestra los archivos cargados; para el sitio web ayuda php_ini_loaded_file() en un archivo de prueba colocado de forma breve.

¿En qué orden se leen los archivos de la carpeta conf.d?

Según el manual de PHP, PHP lee todos los archivos con la extensión .ini del directorio de escaneo en orden alfabético. Los archivos posteriores sobrescriben los valores de los anteriores. Por eso muchos archivos llevan números como 20- o 99- en el nombre.

¿Por qué no surte efecto mi cambio en el php.ini?

Motivos frecuentes: se modificó el archivo de otra SAPI, no se reinició el servicio, un valor en el pool de FPM, en la configuración de Apache o en un .user.ini lo sobrescribe, o un panel de hosting vuelve a escribir el archivo la próxima vez que se guarda.

¿Qué es memory_hard_limit_percent?

Un ajuste nuevo que, según el manual de PHP, se introdujo con las versiones de seguridad del 21/10/2026. Fija un límite de memoria duro como porcentaje de memory_limit. El manual advierte de que una versión de PHP que no conozca este ajuste está afectada por las vulnerabilidades de PHP2Shell.

Fuentes

Contacto inmediato

Cada hora cuenta. Escríbanos ahora.

Describa brevemente el sistema, la versión de PHP y lo que ha observado. Nos pondremos en contacto, aclararemos la situación y trabajaremos en remoto hasta que el incidente quede cerrado y documentado.

Ayuda inmediata