Versão do Documento: 1.0
Data: Março de 2026
Autor: Equipe de Desenvolvimento SETIC
Atualizar a aplicação e-Estado do PHP 7.3 para PHP 8.1.34 e CodeIgniter 3.1.10 para 3.1.13 para manter segurança, desempenho e compatibilidade com infraestrutura moderna.
| Componente | De | Para |
|---|---|---|
| PHP | 7.3 | 8.1.34 |
| CodeIgniter | 3.1.10 | 3.1.13 |
| Imagem Base Docker | php:7.3-fpm | php:8.1-fpm |
Esta seção aborda as principais mudanças introduzidas no PHP 8.0 e PHP 8.1 que afetaram o upgrade da aplicação e-Estado.
Mudança: O PHP 8.0 introduziu verificação de tipos mais rigorosa, particularmente para acesso a propriedades e arrays.
Impacto no e-Estado:
// PHP 7.3 - Tolerante (converte automaticamente)
$json_string = '{"nome": "Teste"}';
echo $json_string->nome; // Warning, mas pode funcionar
// PHP 8.0+ - Erro rigoroso
$json_string = '{"nome": "Teste"}';
echo $json_string->nome; // ERRO: Tentativa de ler propriedade em string
Áreas Afetadas:
Mudança: Funções agora podem ser chamadas com parâmetros nomeados.
Impacto: Baixo - O CodeIgniter 3 e nossa base de código não utilizam extensivamente este recurso ainda.
Exemplo:
// PHP 8.0+ - Argumentos nomeados
htmlspecialchars($string, double_encode: false, encoding: 'UTF-8');
Mudança: Nova expressão match como alternativa mais segura ao switch.
Impacto: Nenhum - Pode ser adotado gradualmente em código novo.
Exemplo:
// Estilo antigo
switch ($status) {
case 'draft': $label = 'Rascunho'; break;
case 'published': $label = 'Publicado'; break;
default: $label = 'Desconhecido';
}
// PHP 8.0+ match (mais rigoroso, retorna valor)
$label = match($status) {
'draft' => 'Rascunho',
'published' => 'Publicado',
default => 'Desconhecido'
};
Mudança: Novo operador ?-> para acesso seguro a propriedades em objetos potencialmente nulos.
Impacto: Positivo - Pode ser usado para simplificar verificações de null.
Exemplo:
// PHP 7.3
$nome = isset($pessoa->endereco) ? $pessoa->endereco->cidade : null;
// PHP 8.0+
$nome = $pessoa->endereco?->cidade;
Mudança: Parâmetros de função e tipos de retorno agora podem especificar múltiplos tipos.
Impacto: Baixo para o upgrade, benéfico para código novo.
Exemplo:
// PHP 8.0+
function processar(int|float $numero): string|null {
return $numero > 0 ? (string)$numero : null;
}
Mudança: Propriedades de classe podem ser declaradas e inicializadas nos parâmetros do construtor.
Impacto: Nenhum para código existente, útil para novas classes.
Exemplo:
// PHP 7.3
class Bem {
private $id;
private $nome;
public function __construct($id, $nome) {
$this->id = $id;
$this->nome = $nome;
}
}
// PHP 8.0+
class Bem {
public function __construct(
private $id,
private $nome
) {}
}
Mudança: throw agora pode ser usado como expressão.
Impacto: Baixo - Pode simplificar o tratamento de erros em código novo.
Exemplo:
// PHP 8.0+
$valor = $data['valor'] ?? throw new Exception('Valor obrigatório');
Mudança: Nova classe WeakMap para mapas com chaves de objeto com coleta de lixo.
Impacto: Nenhum para a base de código atual.
Mudança: Nova interface para objetos que podem ser convertidos para string.
Impacto: Baixo - Útil para código novo, não quebra código existente.
Mudança: Métodos agora podem declarar static como tipo de retorno.
Impacto: Nenhum para código existente.
Mudança: Acessar chaves de array indefinidas agora lança avisos (warnings) em vez de avisos (notices).
Impacto no e-Estado: ALTO
Exemplo:
// PHP 7.3 - Notice
$value = $_POST['servidor_id']; // Notice: Undefined index
// PHP 8.1 - Warning
$value = $_POST['servidor_id']; // Warning: Undefined array key "servidor_id"
Arquivos Afetados: 6 arquivos de controller
Correção Aplicada:
// Usar operador de coalescência nula
$value = $_POST['servidor_id'] ?? null;
// Ou verificação com isset()
if (isset($_POST['servidor_id'])) {
$value = $_POST['servidor_id'];
}
Mudança: Funções internas são mais rigorosas quanto a valores null.
Impacto: Médio
Exemplo:
// PHP 7.3 - Tolerante
strlen(null); // Retorna 0
// PHP 8.1 - Aviso de depreciação
strlen(null); // Deprecated: strlen(): Passing null to parameter of type string
Padrão de Correção:
// Adicionar verificações de null
$length = $string !== null ? strlen($string) : 0;
// Ou usar coalescência nula
$length = strlen($string ?? '');
Mudança: Interface Serializable depreciada em favor de __serialize() e __unserialize().
Impacto: Baixo - O CodeIgniter lida com a maioria da serialização internamente.
Mudança: Classes internas do PHP agora possuem declarações de tipo de retorno apropriadas.
Impacto: Baixo - Pode afetar classes internas estendidas.
Mudança: Novo tipo enum para definir um conjunto fixo de valores.
Impacto: Nenhum para código existente, útil para novos recursos.
Exemplo:
// PHP 8.1+
enum Status: string {
case DRAFT = 'draft';
case PUBLISHED = 'published';
case ARCHIVED = 'archived';
}
// Uso
function setStatus(Status $status) {
// Manipulação de status com segurança de tipo
}
Mudança: Propriedades agora podem ser marcadas como readonly.
Impacto: Nenhum para código existente.
Exemplo:
// PHP 8.1+
class Bem {
public function __construct(
public readonly int $id,
public readonly string $tombamento
) {}
}
Mudança: Nova sintaxe para criar closures a partir de callables.
Impacto: Baixo - açúcar sintático para código novo.
Exemplo:
// PHP 7.3
$fn = Closure::fromCallable([$this, 'method']);
// PHP 8.1+
$fn = $this->method(...);
Mudança: Nova API de fibers para multitarefa cooperativa.
Impacto: Nenhum para a base de código atual.
Mudança: Funções que sempre lançam exceção ou encerram podem declarar tipo de retorno never.
Impacto: Baixo - útil para funções de tratamento de erros.
Exemplo:
// PHP 8.1+
function fail(string $message): never {
throw new Exception($message);
}
Mudança: Constantes de classe agora podem ser declaradas como final.
Impacto: Nenhum para código existente.
Depreciado em: PHP 8.1
Descrição: Criar arrays a partir de valores false.
Exemplo:
// Depreciado
$array = false;
$array[] = 2; // Deprecated: Automatic conversion of false to array
Impacto: Baixo - Não é comumente usado na base de código.
Depreciado em: PHP 8.1
Descrição: Conversões implícitas de estreitamento de float para int.
Exemplo:
// Depreciado
$a = [];
$a[15.5] = 'value'; // Deprecated: Implicit conversion from float to int
Impacto: Baixo
Depreciado em: PHP 8.3 (futuro)
Descrição: Chamar essas funções sem argumentos dentro de métodos.
Impacto: Nenhum ainda - PHP 8.1 não deprecia isso.
Benefício: Compilação Just-In-Time para código com uso intensivo de CPU.
Impacto: ~10-30% de melhoria de desempenho para operações intensivas de CPU.
Benefício para o e-Estado: Geração de PDF mais rápida, cálculos complexos.
Benefício: Carregar framework e arquivos frequentemente usados na memória durante a inicialização.
Impacto: Redução da sobrecarga do opcache, tempos de resposta mais rápidos.
Configuração:
# php.ini
opcache.preload=/var/www/preload.php
opcache.preload_user=www-data
Benefício: Melhor otimização pelo motor do PHP devido a tipagem mais rigorosa.
Impacto: Melhorias marginais de desempenho em toda a aplicação.
Benefício: Implementações mais eficientes de funções internas.
Impacto: Operações com arrays mais rápidas, manipulação de strings, codificação/decodificação JSON.
Usado em: Arquivos de view para acesso seguro a propriedades.
Exemplo:
// Código novo pode usar
<?= $bem->departamento?->sigla ?>
// Em vez de
<?= isset($bem->departamento) ? $bem->departamento->sigla : null ?>
Uso potencial: Manipulação de status, mapeamento de tipos.
Exemplo:
// Pode ser adotado em código novo
$status_label = match($bem->situacao_id) {
1 => 'Ativo',
2 => 'Inativo',
3 => 'Em manutenção',
default => 'Desconhecido'
};
Uso potencial: Arrays de configuração, chamadas de funções complexas.
Exemplo:
// Configuração mais legível
$mpdf = new \Mpdf\Mpdf(
mode: 'utf-8',
format: 'A4',
margin_left: 10,
margin_right: 10
);
| Mudança | Nível de Impacto | Arquivos Afetados | Solução |
|---|---|---|---|
| Acesso rigoroso a propriedades em strings | 🔴 ALTO | 496 views | Helper auto_decode_view_data() |
| Avisos de chave de array indefinida | 🟡 MÉDIO | 6 controllers | Coalescência nula ?? |
| Null em parâmetros não-anuláveis | 🟡 MÉDIO | Múltiplos | Verificações de null e valores padrão |
| Tipos de retorno de funções internas | 🟢 BAIXO | Nenhum | Sem alterações necessárias |
| Depreciação do Serializable | 🟢 BAIXO | Nenhum | CodeIgniter lida internamente |
| Melhorias de desempenho | ✅ POSITIVO | Todos | Benefício automático |
| Novos recursos da linguagem | ✅ POSITIVO | Código novo | Pode ser adotado gradualmente |
Legenda:
// composer.json
{
"require": {
"php": ">=8.1.0"
}
}
Todas as extensões do PHP 7.3 permanecem compatíveis:
# Extensões necessárias
extension=pdo_pgsql
extension=redis
extension=gd
extension=mbstring
extension=curl
extension=xml
extension=zip
extension=intl
Algumas configurações do php.ini possuem novos padrões ou opções:
# Configurações recomendadas do PHP 8.1 para o e-Estado
memory_limit = 512M
max_execution_time = 300
upload_max_filesize = 100M
post_max_size = 100M
# Relatório de erros (desenvolvimento)
error_reporting = E_ALL
display_errors = On
# Relatório de erros (produção)
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
log_errors = On
# Configuração JIT (opcional)
opcache.enable=1
opcache.jit_buffer_size=100M
opcache.jit=tracing
Backup do Sistema Atual
git checkout -b feat/upgrade-php
git tag backup-before-upgrade
Download do CodeIgniter 3.1.13
cd /tmp
wget https://github.com/bcit-ci/CodeIgniter/archive/3.1.13.tar.gz
tar -xzf 3.1.13.tar.gz
Substituir Diretório System
rm -rf system/
cp -r /tmp/CodeIgniter-3.1.13/system /var/www/system
Atualizar index.php
Testar Funcionalidade Básica
vendor/bin/phpunit -c application/tests
Resultado: ✅ CodeIgniter atualizado com sucesso, todos os testes passando.
Atualizar Dockerfile
# Antes
FROM php:7.3-fpm
# Depois
FROM php:8.1-fpm
Reconstruir Imagem Docker
docker-compose down
docker-compose build --no-cache
docker-compose up -d
Atualizar composer.json
{
"require": {
"php": ">=8.1"
}
}
Reinstalar Dependências
docker-compose exec eestado_app composer install
Resultado: ✅ PHP atualizado, contêiner Docker funcionando com sucesso.
Esta fase tratou das mudanças incompatíveis introduzidas pelo sistema de tipos rigoroso do PHP 8.1.
Problema: A função TO_JSON() do PostgreSQL retorna JSON como strings, não objetos. O acesso rigoroso a propriedades do PHP 8.1 causa erros ao tentar acessar propriedades nessas strings.
Exemplo de Erro:
Attempt to read property "nome" on string
na linha: $registro->descricao_sintetica->nome
Causa Raiz:
// Resultado da consulta PostgreSQL
$result = $this->db->query("
SELECT
b.*,
TO_JSON(ds.*) as descricao_sintetica
FROM bens b
LEFT JOIN descricao_sintetica ds ON ds.id = b.descricao_sintetica_id
")->result();
// No PHP 7.3 - tolerante, converte automaticamente
echo $result[0]->descricao_sintetica->nome; // Funciona
// No PHP 8.1 - verificação rigorosa de tipos
echo $result[0]->descricao_sintetica->nome; // ERRO: string não possui ->nome
Problema: Objetos JSON aninhados (3+ níveis de profundidade) requerem decodificação recursiva.
Exemplo:
// Nível 1: $registro (objeto)
// Nível 2: $registro->registros (string JSON)
// Nível 3: $contexto->tabela (string JSON)
// Nível 4: $contexto->tabela->nome (acesso a propriedade falha)
foreach ($registro->registros as $contexto) {
echo $contexto->tabela->nome; // ERRO
}
Problema: Dados passados para funções como parâmetros não eram decodificados pelo auto-decode no nível da view.
Exemplo:
// Arquivo de view - auto_decode funciona aqui
auto_decode_view_data($this->data);
extract($this->data);
// Mas parâmetros de função não são afetados
function htmlHeader($comprovante_ingresso) {
// $comprovante_ingresso ainda é string JSON
echo $comprovante_ingresso->forma_ingresso->nome; // ERRO
}
Problema: PHP 8.1 lança avisos (warnings) para chaves de array indefinidas (anteriormente notices).
Exemplo:
// PHP 7.3 - Notice
$value = $_POST['servidor_id']; // Notice se não definido
// PHP 8.1 - Warning
$value = $_POST['servidor_id']; // Warning se não definido
Problema: Arquivos de cache de fontes do mPDF criados com permissões restritivas em montagens de volume Docker.
Erro:
Permission denied: /var/www/uploads/comprovante_ingresso/ttfontdata/dejavuserifcondensed.mtx.json
Criado um sistema abrangente de helpers para decodificar automaticamente strings JSON em toda a aplicação.
Controller → View → Função Helper → App_Model → Dados Decodificados
application/helpers/json_decoder_helper.phpApp_Model::decode_json_result()autoload.phpauto_decode_view_data(&$data_array)Propósito: Decodificar automaticamente variáveis comuns da view quando uma view é carregada.
Localização: application/helpers/json_decoder_helper.php
Uso:
<?php
// No topo de qualquer arquivo de view
auto_decode_view_data($this->data);
extract($this->data);
Como Funciona:
function auto_decode_view_data(&$data_array) {
if (!is_array($data_array)) return;
$CI =& get_instance();
$CI->load->model('App_Model', 'json_decoder_model');
// Lista de nomes de variáveis comuns usadas em toda a aplicação
$common_vars = [
'query', 'bem', 'registro', 'item',
'guardas_em_andamento', 'guardas_finalizadas',
'historico', 'pre_inc', 'movimentacao',
'chefes', 'departamento', 'baixa', 'depreciacoes',
'tipo', 'forma', 'ocorrencias', 'ocorrencia',
'dependentes', 'dependente', 'registros',
'tabela', 'metadados', 'metadata'
];
// Decodifica cada variável se existir
foreach ($common_vars as $var) {
if (isset($data_array[$var])) {
$data_array[$var] = $CI->json_decoder_model->decode_json_result($data_array[$var]);
}
}
// Também decodifica no escopo global para variáveis extraídas
foreach ($common_vars as $var) {
if (isset($GLOBALS[$var])) {
$GLOBALS[$var] = $CI->json_decoder_model->decode_json_result($GLOBALS[$var]);
}
}
}
Benefícios:
$this->data quanto variáveis extraídasjson_safe($data)Propósito: Decodificador inline rápido para casos especiais e parâmetros de função.
Localização: application/helpers/json_decoder_helper.php
Uso:
// Caso especial 1: Aninhamento profundo em loops
foreach ($registro->registros as $contexto) {
$contexto = json_safe($contexto); // Decodifica JSON aninhado
echo $contexto->tabela->nome; // Agora funciona
}
// Caso especial 2: Parâmetros de função
function htmlHeader($comprovante_ingresso) {
$comprovante_ingresso = json_safe($comprovante_ingresso);
echo $comprovante_ingresso->forma_ingresso->nome; // Agora funciona
}
Como Funciona:
function json_safe($data) {
static $decoder = null;
if ($decoder === null) {
$CI =& get_instance();
$CI->load->model('App_Model');
$decoder = $CI->App_Model;
}
return $decoder->decode_json_result($data);
}
Benefícios:
decode_json(&$data)Propósito: Wrapper de decodificador manual com modificação por referência.
Localização: application/helpers/json_decoder_helper.php
Uso:
// Decodifica uma variável por referência
decode_json($my_data);
echo $my_data->property;
Como Funciona:
function decode_json(&$data) {
$CI =& get_instance();
$CI->load->model('App_Model', 'json_decoder_model');
$data = $CI->json_decoder_model->decode_json_result($data);
return $data;
}
App_Model::decode_json_result($data)Propósito: Decodificador JSON recursivo central no modelo base.
Localização: application/models/App_Model.php (linhas 638-717)
Como Funciona:
public function decode_json_result($data)
{
// Manipula NULL
if ($data === null) {
return null;
}
// Manipula arrays - decodifica recursivamente cada elemento
if (is_array($data)) {
foreach ($data as $key => $value) {
$data[$key] = $this->decode_json_result($value);
}
return $data;
}
// Manipula objetos - decodifica recursivamente cada propriedade
if (is_object($data)) {
foreach ($data as $key => $value) {
$data->$key = $this->decode_json_result($value);
}
return $data;
}
// Manipula strings JSON - decodifica e recursiona
if (is_string($data)) {
$decoded = json_decode($data);
if (json_last_error() === JSON_ERROR_NONE && ($decoded !== null)) {
return $this->decode_json_result($decoded);
}
}
// Retorna tipos primitivos como estão
return $data;
}
Benefícios:
Mensagem de Erro:
Attempt to read property "nome" on string
Causa: String JSON não decodificada antes do acesso à propriedade.
Padrão de Correção 1 - Nível da View (aplica-se a 95% dos casos):
<?php
// ⚡ PHP 8.1 FIX: Auto-decode all view data
auto_decode_view_data($this->data);
extract($this->data);
?>
<!-- Agora todas as variáveis comuns estão decodificadas -->
<p><?= $registro->descricao_sintetica->nome ?></p>
Padrão de Correção 2 - Aninhamento Profundo:
<?php foreach ($registro->registros as $contexto): ?>
<?php $contexto = json_safe($contexto); // Decodifica JSON aninhado ?>
<span><?= $contexto->tabela->nome; ?></span>
<?php endforeach; ?>
Padrão de Correção 3 - Parâmetros de Função:
function htmlHeader($comprovante_ingresso)
{
// ⚡ PHP 8.1 FIX: Decode JSON in function parameter
$comprovante_ingresso = json_safe($comprovante_ingresso);
$html = "<strong>" . $comprovante_ingresso->forma_ingresso->nome . "</strong>";
return $html;
}
Arquivos Corrigidos: 496 arquivos de view, 6 arquivos de controller
Mensagem de Erro:
Undefined array key "servidor_id"
Causa: Avisos rigorosos de chave indefinida do PHP 8.1.
Padrão de Correção:
// Antes (PHP 7.3)
$servidor_id = $post['servidor_id'];
// Depois (PHP 8.1)
$servidor_id = $post['servidor_id'] ?? null;
// OU usar variável já extraída
$servidor_id = $servidor_id; // definida anteriormente na função
Exemplo:
// application/controllers/Recursos_humanos/Ocorrencia.php:344
// Antes
$ocorrencia->servidor_id = $post['servidor_id'];
// Depois
$ocorrencia->servidor_id = $servidor_id; // Já definido do BD
Mensagem de Erro:
Permission denied: /var/www/uploads/comprovante_ingresso/ttfontdata/dejavuserifcondensed.mtx.json
Causa: Problemas de permissão de montagem de volume Docker com cache de fontes.
Correção:
# Remover cache antigo
docker-compose exec eestado_app rm -rf /var/www/uploads/comprovante_ingresso/ttfontdata
# Recriar com permissões adequadas
docker-compose exec eestado_app mkdir -p /var/www/uploads/comprovante_ingresso/ttfontdata
docker-compose exec eestado_app chmod 777 /var/www/uploads/comprovante_ingresso/ttfontdata
Solução Permanente (adicionar ao Dockerfile):
RUN mkdir -p /var/www/uploads/comprovante_ingresso/ttfontdata && \
chmod 777 /var/www/uploads/comprovante_ingresso/ttfontdata
Erro: Sessões não persistindo entre requisições.
Correção: Atualizado application/libraries/Sessao.php para usar Redis adequadamente:
// Garantir conexão Redis antes de operações de sessão
if (!$this->redis->ping()) {
$this->redis->connect();
}
Para aplicar o padrão auto_decode_view_data() em toda a base de código de forma eficiente, uma abordagem multi-agente foi utilizada.
# O agente recebeu esta tarefa:
"Aplicar padrão auto_decode_view_data em todos os arquivos de view em application/views/"
| Categoria | Quantidade | Ação |
|---|---|---|
| Total de arquivos de view | 1.136 | Varridos |
| Arquivos atualizados | 461 | Padrão adicionado |
| Arquivos com padrão | 35 | Ignorados (já possuíam) |
| Views estáticas | 632 | Ignoradas (sem $this->data) |
| Arquivos de template | 8 | Excluídos |
| Erros | 0 | 100% de taxa de sucesso |
| Módulo | Arquivos Atualizados |
|---|---|
| Patrimonio | 173 |
| Cadastro_geral | 66 |
| Acordos | 60 |
| Relatorios | 30 |
| Compras | 30 |
| Recursos_humanos | 29 |
| Outros | 73 |
/tmp/view_files_updated.txt - Lista completa de arquivos atualizados/tmp/view_files_skipped.txt - Arquivos que não precisaram de atualização/tmp/view_update_summary.txt - Estatísticas e detalhamento# Executar todos os testes
vendor/bin/phpunit -c application/tests
# Executar com saída detalhada
vendor/bin/phpunit --testdox -c application/tests
Resultado: Todos os testes passando após o upgrade.
# Testar autenticação
curl -X POST http://localhost:8000/login \
-d "username=admin" \
-d "password=pass"
Logs de erros do PHP utilizados para identificar problemas:
# Monitorar erros do PHP
docker-compose exec eestado_app tail -f /var/log/php8.1-fpm.log
# Verificar logs da aplicação
docker-compose logs -f eestado_app
Testados todos os recursos previamente funcionais:
| Arquivo | Alterações |
|---|---|
Dockerfile |
Imagem base atualizada para php:8.1-fpm |
composer.json |
Requisito de PHP atualizado para >=8.1 |
application/config/autoload.php |
Helper json_decoder adicionado ao auto-load |
| Arquivo | Propósito |
|---|---|
application/helpers/json_decoder_helper.php |
Funções helper de decodificação JSON |
| Arquivo | Linhas | Alterações |
|---|---|---|
application/models/App_Model.php |
638-717 | Método decode_json_result() adicionado |
application/libraries/Sessao.php |
Múltiplas | Correção na manipulação de conexão Redis |
application/controllers/BaseController.php |
Múltiplas | Atualizações na inicialização de sessão |
Total: 496 arquivos de view
Padrão Aplicado:
<?php
// ⚡ PHP 8.1 FIX: Auto-decode all view data
auto_decode_view_data($this->data);
extract($this->data);
Exemplos Principais:
application/views/Patrimonio/Bem/detalhes.phpapplication/views/Patrimonio/Bem/comprovante_ingresso.phpapplication/views/Patrimonio/Bem_pre_incorporacao/comprovante_ingresso.phpapplication/views/Recursos_humanos/Servidor/relatorio_ocorrencias.phpapplication/views/Configuracoes/Metakey/index.phpapplication/views/Cadastro_geral/Pessoa_fisica/detalhes.phpTotal: 6 arquivos de controller
Arquivos:
application/controllers/Recursos_humanos/Ocorrencia.php (linhas 256, 286, 344)application/controllers/Recursos_humanos/Chefe_departamento.php (linha 129)application/controllers/Cadastro_geral/Pessoa_fisica_nivel_escolaridade.php (linhas 155, 173)application/controllers/Patrimonio/Termo_responsabilidade.php (linha 114)application/controllers/Cadastro_geral/Pessoa_documento.php (linha 126)Sempre incluir o padrão de auto-decode no topo de novos arquivos de view:
<?php
// ⚡ PHP 8.1 FIX: Auto-decode all view data
auto_decode_view_data($this->data);
extract($this->data);
Ao criar funções que recebem dados como parâmetros, decodificá-los:
function myFunction($data) {
// ⚡ PHP 8.1 FIX: Decode JSON in function parameter
$data = json_safe($data);
// Resto da função
}
Usar json_safe() inline ao lidar com 3+ níveis de aninhamento:
foreach ($items as $item) {
$item = json_safe($item);
echo $item->nested->property->name;
}
Se uma nova variável comum é usada em muitas views, adicioná-la à lista em json_decoder_helper.php:
$common_vars = [
'query', 'bem', 'registro', 'item',
// ... variáveis existentes ...
'sua_nova_variavel' // Adicionar aqui
];
Considerar modificar consultas para reduzir o uso de JSON:
// Antes - usa TO_JSON (retorna string)
SELECT TO_JSON(ds.*) as descricao_sintetica FROM descricao_sintetica ds
// Melhor - selecionar colunas específicas
SELECT ds.id, ds.nome, ds.codigo FROM descricao_sintetica ds
No entanto, isso pode exigir refatoração significativa. A abordagem com decodificador é mais prática para a base de código existente.
Continuar monitorando logs de erro do PHP após a implantação:
docker-compose exec eestado_app tail -f /var/log/php8.1-fpm.log
Para código novo, aplicar esses padrões nas revisões de código:
auto_decode_view_data()json_safe()json_safe() inline$_POST ou $_GET sem coalescência nulaManter este documento atualizado com:
O decodificador JSON recursivo adiciona sobrecarga mínima:
$this->data['bem'] = $this->bem_model->get_by_id($id);
// Decodificador executa na view, mas apenas uma vez
// Em vez de aninhamento profundo via JOINs
// Considerar consultas separadas e montagem manual
json_safe():// Já implementado - instância do decodificador é cacheada
static $decoder = null;