Situação atual: PHP2Shell. Duas vulnerabilidades críticas do PHP (CVSS 9,2) permitem executar código malicioso sem autenticação. Patches disponíveis desde 21/10/2026.O que fazer agora →

O php.ini explicado: estrutura, níveis e precedência

Onde o PHP encontra as suas definições, por que ordem atuam e quem as pode sobrescrever. Base para qualquer reforço e para as medidas transitórias contra o PHP2Shell.

Atualizado em 5 min de leituraConhecimento PHP

Em resumo: O php.ini é o ficheiro de configuração central do PHP. O PHP lê-o no arranque: nos módulos de servidor uma vez, no CGI e na CLI a cada chamada. A isso juntam-se ficheiros adicionais de uma pasta de varrimento, definições no pool FPM ou no Apache, .htaccess ou .user.ini e ini_set() no código. Que nível pode alterar um valor é determinado pelo seu modo de alteração, por exemplo INI_SYSTEM ou INI_PERDIR. Valores definidos com php_admin_value a aplicação já não consegue sobrescrever.

O que é o php.ini?

O php.ini é um ficheiro de texto com entradas no formato name = wert. Define como o PHP se comporta: quanta memória um script pode usar, se os erros aparecem no navegador, como funcionam as sessões e que extensões são carregadas. Os comentários começam com ponto e vírgula.

Segundo o manual do PHP, o ficheiro é lido no arranque do PHP. Nos módulos de servidor como o mod_php isso acontece apenas uma vez, no arranque do servidor web; no CGI e na CLI, a cada chamada. O PHP-FPM lê a sua configuração no arranque e ao recarregar o serviço. Uma alteração sem reinício ou reload não faz, por isso, normalmente efeito.

Desde o PHP 8.3, segundo o manual, uma entrada pode remeter para uma variável de ambiente com valor de substituição:

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

Onde procura o PHP o php.ini?

O manual descreve uma ordem fixa. Primeiro vale um caminho expressamente definido, por exemplo PHPIniDir no Apache ou a opção -c no CGI e na CLI. Caso contrário, o PHP constrói um caminho de pesquisa a partir de:

  1. da variável de ambiente PHPRC,
  2. no Windows, da entrada de registo IniFilePath,
  3. da pasta de trabalho atual, exceto nas SAPI que o desativam, como a CLI,
  4. da pasta do binário PHP ou do módulo,
  5. do caminho --with-config-file-path definido na compilação.

Neste caminho de pesquisa, o PHP procura primeiro um ficheiro php-SAPI.ini, por exemplo php-cli.ini, e só depois o php.ini. Em seguida, o PHP lê por ordem alfabética todos os ficheiros .ini da pasta de varrimento, definida através de PHP_INI_SCAN_DIR ou, na compilação, através de --with-config-file-scan-dir. Que ficheiros foram carregados mostra-o php --ini ou a função php_ini_scanned_files().

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

Ambos os comandos mostram o estado da linha de comandos. Para o site pode valer outro ficheiro, porque cada SAPI pode ter a sua própria configuração; mais sobre isto em SAPI explicada.

Modos de alteração: quem pode definir que valor?

Nem todas as definições podem ser fixadas em qualquer lado. O manual atribui a cada diretiva um modo de alteração:

Modo Onde o valor pode ser definido
INI_USER em scripts com ini_set(), no registo do Windows e no .user.ini
INI_PERDIR no php.ini, .htaccess, httpd.conf ou .user.ini
INI_SYSTEM apenas no php.ini ou httpd.conf
INI_ALL em qualquer lado

Exemplos do manual: o memory_limit tem o modo INI_ALL e o valor por defeito 128M, o post_max_size tem INI_PERDIR e o valor por defeito 8M, o upload_max_filesize tem INI_PERDIR e o valor por defeito 2M. O expose_php só pode constar do php.ini.

Os ficheiros .user.ini são lidos, segundo o manual, apenas pelas SAPI de CGI e FastCGI, ou seja, também pelo PHP-FPM. O PHP procura-os desde a pasta do script até à raiz de documentos e volta a lê-los, por defeito, no máximo a cada 300 segundos (user_ini.cache_ttl). No mod_php, é o .htaccess que desempenha este papel.

Que valor prevalece no final? Os níveis por precedência

Em termos simplificados: quanto mais tarde um nível atua, mais provável é que o seu valor se imponha, desde que o modo de alteração o permita.

  1. php.ini da respetiva SAPI
  2. Ficheiros adicionais da pasta de varrimento, por ordem alfabética
  3. Configuração do servidor: pool FPM com php_value ou php_admin_value, VirtualHost do Apache
  4. Nível de diretório: .htaccess no mod_php, .user.ini no FPM e CGI
  5. Tempo de execução: ini_set() no código da aplicação

A exceção é decisiva: valores definidos com php_admin_value ou php_admin_flag não podem, segundo o manual, ser sobrescritos com ini_set(). Assim, os administradores bloqueiam definições relevantes para a segurança contra a aplicação. Está descrito em pormenor em php_admin_value: bloquear definições contra sobrescrita.

O php.ini depois do PHP2Shell: o que mudou

As medidas transitórias do php.net para o PHP2Shell são quase todas definições INI: memory_limit=-1 bloqueado contra sobrescrita, um post_max_size limitado, session.upload_progress.enabled=0 e, no PHP 8.5, fatal_error_backtraces=0. O php.net sublinha que session.upload_progress.enabled não deve ser definido através de ini_set() nem de .user.ini, mas no php.ini, no pool FPM ou na configuração do servidor, com reinício posterior de todos os workers. A lista completa está em Medidas imediatas quando ainda não pode aplicar patches.

Com as versões corrigidas 8.5.12, 8.4.27, 8.3.36 e 8.2.35, também o memory_limit mudou, segundo o manual: é agora um limite flexível. A nova definição memory_hard_limit_percent fixa um limite rígido. Sem valor próprio, corresponde ao dobro do memory_limit e, acima de 1G, ao valor mais 1G. Se for excedido, o processo termina de imediato com estado de saída 137. Como escolher com critério os dois limites explica-o Definir o memory_limit corretamente.

Dica

Segundo o manual, vale o seguinte: se uma versão do PHP não reconhece o memory_hard_limit_percent, está afetada pelo CVE-2026-109618 e pelo CVE-2026-109619. Em distribuições com backports, o changelog do pacote comprova adicionalmente o estado.

Como ajuda concretamente a PHP SOS?

  • Apurar os valores efetivos: Lemos, para cada SAPI, que ficheiros são carregados e que valor prevalece no final.
  • Arrumar os níveis: Removemos entradas contraditórias de painéis, pools, .htaccess e .user.ini.
  • Definir bloqueios: No âmbito do reforço de servidores, fixamos os valores relevantes para a segurança com php_admin_value.
  • Comprovar: Documentamos as definições e o reinício, para que o estado possa ser comprovado mais tarde.

Perguntas frequentes

Onde está o php.ini?

Depende do sistema operativo, do pacote e da SAPI. No Debian e no Ubuntu há pastas próprias por versão e SAPI, por exemplo /etc/php/8.3/fpm/php.ini e /etc/php/8.3/cli/php.ini. Na linha de comandos, php --ini mostra os ficheiros carregados; para o site ajuda o php_ini_loaded_file() num ficheiro de teste temporário.

Por que ordem são lidos os ficheiros da pasta conf.d?

Segundo o manual do PHP, o PHP lê todos os ficheiros com a extensão .ini da pasta de varrimento por ordem alfabética. Os ficheiros posteriores sobrescrevem valores dos anteriores. Por isso, muitos ficheiros têm números como 20- ou 99- no nome.

Porque é que a minha alteração ao php.ini não faz efeito?

Motivos frequentes: foi alterado o ficheiro de outra SAPI, o serviço não foi reiniciado, um valor no pool FPM, na configuração do Apache ou num .user.ini sobrescreve-o, ou um painel de alojamento reescreve o ficheiro na gravação seguinte.

O que é o memory_hard_limit_percent?

Uma definição nova que, segundo o manual do PHP, foi introduzida com as versões de segurança de 21/10/2026. Fixa um limite de memória rígido como percentagem do memory_limit. O manual indica que uma versão do PHP que não conheça esta definição está afetada pelas vulnerabilidades do PHP2Shell.

Fontes

Contacto imediato

Cada hora conta. Escreva-nos agora.

Descreva brevemente o sistema, a versão do PHP e o que observou. Entramos em contacto consigo, esclarecemos a situação e trabalhamos remotamente até o incidente estar concluído e documentado.

Ajuda imediata