# O php.ini explicado: estrutura, níveis e precedência

> O php.ini explicado: onde o PHP procura a sua configuração, que níveis existem, o que significam INI_SYSTEM e INI_PERDIR e que valor prevalece no final.

Fonte: https://phpsos.de/pt/php/php-ini-erklaert/  
Atualizado em: 25/10/2026  
Prestador: PHP SOS, Assistência de emergência PHP e segurança de servidores. Ajuda imediata por WhatsApp: https://wa.me/491736494914?text=Ol%C3%A1%2C%20PHP%20SOS%2C%20precisamos%20de%20ajuda%20com%20o%20nosso%20servidor%20PHP.%20Empresa%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**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:

```ini
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()`.

```bash
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](https://phpsos.de/pt/php/sapi-erklaert/).

## 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](https://phpsos.de/pt/blog/php-admin-value-sperren/).

## 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](https://phpsos.de/pt/php2shell/sofortmassnahmen-ohne-patch/).

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](https://phpsos.de/pt/blog/memory-limit-richtig-setzen/).

> **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](https://phpsos.de/pt/leistungen/server-haertung/), 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

- [Manual do PHP: o ficheiro de configuração](https://www.php.net/manual/en/configuration.file.php)
- [Manual do PHP: modos de alteração do INI](https://www.php.net/manual/en/configuration.changes.modes.php)
- [Manual do PHP: ficheiros .user.ini](https://www.php.net/manual/en/configuration.file.per-user.php)
- [Manual do PHP: definições do núcleo](https://www.php.net/manual/en/ini.core.php)
