Guia de Migração do PHP 7.x para o PHP 8.2

Guia de Migração do PHP 7.x para o PHP 8.2

A partir da release 9.13.012, o Scriptcase passa a ser compatível com o PHP 8.2, tanto no ambiente de desenvolvimento quanto em produção.
Ao migrar diretamente do PHP 7.x para o PHP 8.2, códigos personalizados (eventos, métodos e bibliotecas internas ou externas) podem passar a emitir warnings, deprecations ou até apresentar falhas, devido a mudanças de comportamento e à descontinuação de recursos introduzidos nas versões mais recentes do PHP.

Este tutorial reúne os principais pontos de atenção da migração para o PHP 8.2, com explicações e exemplos práticos para facilitar a adaptação do código e reduzir impactos durante a atualização.


1) Operadores ternários aninhados sem parênteses explícitos — Não permitido


Expressões condicionais utilizando operadores ternários aninhados sem parênteses explícitos não são permitidas no PHP 8.2.
Esse tipo de escrita pode gerar ambiguidades e não é mais aceito pelo interpretador.

❌ Exemplo não permitido:
  1. $result = $aa != "" ? $xxx : isset($bb) && $bb != "" ? $zzz : "";

✅ Forma recomendada:
Reescreva a lógica de forma explícita, utilizando estruturas condicionais:
  1. if ($aa != "") {
  2.     $result = $xxx;
  3. } elseif (isset($bb) && $bb != "") {
  4.     $result = $zzz;
  5. } else {
  6.     $result = "";
  7. }

2) Acesso a valores de array e string usando chaves — Deprecated

O acesso a valores de arrays e strings utilizando a sintaxe de chaves {} não é permitido no PHP 8.2.
Esse formato está depreciado e pode gerar warnings ou erros durante a execução.

Utilize sempre a sintaxe com colchetes [] para acessar índices.

❌ Exemplo não permitido:
  1. $array = [1, 2];
  2. echo $array{1};
  3. $string = "foo";
  4. echo $string{0};
Quote
Esse tipo de acesso gera mensagens como:
Deprecated: Array and string offset access syntax with curly braces is deprecated

✅ Forma correta:
  1. $array = [1, 2];
  2. echo $array[1]; // exibe 2
  3. $string = "foo";
  4. echo $string[0]; // exibe "f"

3) Parâmetros obrigatórios após parâmetros opcionais — Deprecated

A declaração de funções ou métodos com parâmetros obrigatórios após parâmetros opcionais não é permitida no PHP 8.2.
Esse tipo de assinatura é considerada incorreta e pode gerar warnings ou deprecations durante a execução.

❌ Exemplo não permitido:
  1. function foo($param_optional = null, $param_required) {
  2.     // ...
  3. }
Quote
Esse tipo de declaração pode gerar mensagens como:
Deprecated: Required parameter $param_required follows optional parameter $param_optional

✅ Forma correta:
Declare sempre os parâmetros obrigatórios primeiro, seguidos pelos opcionais:
  1. function foo($param_required, $param_optional = null) {
  2.     // ...
  3. }

4) Operações aritméticas com strings não numéricas — Não permitido

Operações aritméticas envolvendo strings não numéricas não são permitidas no PHP 8.2.
Esse tipo de operação pode gerar warnings ou erros, pois valores que não representam números não são mais tratados implicitamente como zero.

❌ Exemplo não permitido:
  1. $b = "";
  2. $a = $b + 2;
Quote
Esse tipo de operação pode resultar em erro, pois $b não contém um valor numérico válido.

✅ Forma correta:
Antes de realizar a operação, é necessário garantir que o valor seja numérico.

Exemplo 1 — validação direta:
  1. $a = is_numeric($b) ? $b + 2 : 2;

Exemplo 2 — normalização do valor:
  1. if (!is_numeric($b)) {
  2.     $b = 0;
  3. }
  4. $a = $b + 2;

5) Variáveis e índices inexistentes — Atenção a warnings

O uso de variáveis não definidas ou índices de array inexistentes pode gerar warnings no PHP 8.2.
Esse comportamento ocorre quando o código tenta acessar valores que ainda não foram definidos.

Se a exibição de warnings estiver habilitada, esse tipo de situação pode resultar em mensagens frequentes durante a execução do código.

❌ Exemplo não permitido:
  1. $a = $b + 2;
Ou:
  1. $a = $array['key'] + 2;
Quote
Quando $b ou $array['key'] não existem, um warning pode ser exibido.

✅ Forma correta:
Antes de utilizar uma variável ou índice de array, verifique se ele existe.
  1. $a = isset($b) ? $b + 2 : 2;
Ou, no caso de arrays:
  1. $a = isset($array['key']) ? $array['key'] + 2 : 2;

6) Função each() — Removida


A função each() retorna o par chave/valor atual de um array e avança o seu cursor interno.

Essa função não está disponível no PHP 8.2.
Caso ela seja utilizada em suas aplicações, o código precisa ser alterado antes da publicação em um ambiente com PHP 8.2 ou superior.

Opções comuns de substituição:
  1. foreach()
  2. key()
  3. current()
  4. next()

❌ Exemplo não suportado:
  1. $result = "";

  2. $tab = array(
  3.     0 => array('tp' => 1, 'vl' => 'aaa'),
  4.     1 => array('tp' => 2, 'vl' => 'bbb'),
  5.     2 => array('tp' => 3, 'vl' => 'ccc')
  6. );

  7. while (list($key, $val) = each($tab)) {
  8.     $result .= $tab[$key]["vl"];
  9. }

✅ Forma recomendada (usando foreach()):
  1. $result = "";

  2. $tab = array(
  3.     0 => array('tp' => 1, 'vl' => 'aaa'),
  4.     1 => array('tp' => 2, 'vl' => 'bbb'),
  5.     2 => array('tp' => 3, 'vl' => 'ccc')
  6. );

  7. foreach ($tab as $key => $val) {
  8.     $result .= $tab[$key]["vl"];
  9. }

7) Função array_key_exists() — Uso em objetos deprecated

A função array_key_exists() verifica se uma chave ou índice existe em um array.
No PHP 8.2, o uso dessa função para verificar propriedades de objetos está deprecated.

Para esse cenário, utilize isset() ou property_exists().

❌ Exemplo não recomendado:
  1. if (array_key_exists('index', $array1)) {
  2.     // código
  3. }
✅ Forma recomendada:
  1. if (isset($array1['index'])) {
  2.     // código
  3. }

8) Função money_format() — Removida

A função money_format() formata um número como uma string de moeda.

Essa função não está disponível no PHP 8.2.
Para realizar a formatação monetária, utilize a extensão Intl, por meio da classe NumberFormatter.

❌ Exemplo não suportado:
  1. echo money_format("%.2n", 1234.56);
✅ Forma recomendada (usando NumberFormatter):
  1. $currencyObject = new NumberFormatter("pt-BR", NumberFormatter::CURRENCY);
  2. echo $currencyObject->format(1234.56);

9) Função mb_strrpos() — Parâmetro de encoding deprecated

A função mb_strrpos() localiza a posição da última ocorrência de um valor em uma string.

No PHP 8.2, informar a codificação como terceiro parâmetro está deprecated.
Em vez disso, passe um offset como terceiro parâmetro e a codificação como quarto.

❌ Exemplo não recomendado:
  1. $string = 'O rato roeu a roupa';
  2. echo mb_strrpos($string, 'roeu', 'UTF-8');
✅ Forma correta:
  1. $string = 'O rato roeu a roupa';
  2. echo mb_strrpos($string, 'roeu', 0, 'UTF-8');

10) Propriedades dinâmicas (dynamic properties) — Deprecated

No PHP 8.2, criar propriedades que não existem na classe diretamente em um objeto (por exemplo, obj->nova = 1;) passou a gerar deprecation.
Esse comportamento só é permitido quando a própria classe autoriza a criação dinâmica de propriedades ou quando o objeto é do tipo stdClass.

Antes (sem aviso):
Era possível criar propriedades dinamicamente em objetos sem que o PHP emitisse qualquer aviso.
  1. class User {} $u = new User();
  2. $u->name = "Ana"; // dynamic property
PHP 8.2 (gera deprecation):
Esse tipo de uso passou a gerar deprecation. Para evitar o aviso, você pode:
  1. Declarar a propriedade diretamente na classe;
    Usar o atributo #[\AllowDynamicProperties] (solução paliativa);
    Utilizar WeakMap quando você não tem controle sobre a classe.

11) “Relative callables” — Deprecated

Alguns formatos de callable que funcionavam com call_user_func(), mas não funcionam corretamente quando executados como $callable(), passaram a ser marcados como deprecated no PHP 8.2. Isso inclui chamadas que dependem do contexto da classe, como "self::method", "parent::method", "static::method" e ["self", "method"]

Evite usar:
  1. call_user_func("self::doStuff");
  2. call_user_func(["self", "doStuff"]);
Use no lugar:
O nome completo da classe:
  1. call_user_func("MinhaClasse::doStuff");
  2. call_user_func(["MinhaClasse", "doStuff"]);
Ou uma closure, quando precisar acessar o contexto atual:
  1. call_user_func(fn() => $this->doStuff());

12) Interpolação "${var}" e "${expr}" em strings — Deprecated

No PHP 8.2, o uso de interpolação no formato "${var}" e "${expr}" em strings passou a ser deprecated, pois esse estilo é menos claro e pode causar ambiguidade.

Evite:
  1. echo "Olá ${name}";
  2. echo "Total: ${arr['total']}";
Use:
  1. echo "Olá $name";
  2. echo "Olá {$name}";
  3. echo "Total: {${arr['total']}}"; // para expressões

13) utf8_encode() e utf8_decode() — Deprecated

As funções utf8_encode() e utf8_decode() foram marcadas como deprecated no PHP 8.2, pois assumem um encoding fixo, o que pode gerar resultados incorretos em diferentes cenários.
Substituições comuns:
  1. mb_convert_encoding($str, 'UTF-8', 'ISO-8859-1') // ajuste o encoding de origem conforme o caso
  2. iconv('ISO-8859-1', 'UTF-8//TRANSLIT', $str) // quando aplicável
Quote
Essas funções assumem o encoding ISO-8859-1 como padrão, o que pode causar confusão e conversões incorretas; por isso foram descontinuadas.

14) Funções “case-insensitive” e conversão de maiúsculas/minúsculas — Mudança de comportamento

No PHP 8.2, várias funções que convertem ou comparam texto ignorando maiúsculas e minúsculas passaram a usar regras ASCII (locale padrão “C”). Isso inclui funções como strtolower(), strtoupper(), ucwords() e str_ireplace().
Com essa mudança, essas funções não consideram mais regras específicas de idioma, o que pode afetar textos com acentuação ou idiomas com regras próprias de capitalização, como português (pt-BR) e turco (tr-TR).

Para trabalhar corretamente com textos localizados ou caracteres acentuados, utilize a extensão MBString, por exemplo:
  1. mb_strtolower($texto, 'UTF-8');

15) glob() com open_basedir — Mudança no retorno

No PHP 8.2, o comportamento da função glob() mudou quando a diretiva open_basedir está ativo.
  1. Se todos os caminhos forem bloqueados pelo open_basedir, glob() passa a retornar um array vazio ([]) — antes, o retorno era false.
  2. Se apenas alguns caminhos forem bloqueados, um warning pode ser exibido.
Código que pode ser afetado:
  1. $files = glob($pattern);
  2. if ($files === false) {
  3.     // ...
  4. }



Ajuste recomendado:
Atualize a verificação para considerar também o retorno [], garantindo que o código trate corretamente os dois cenários.

Correção (tratar false e []):
  1. $files = glob($pattern);
  2. if ($files === false || $files === []) {
  3.     // Nenhum arquivo encontrado OU acesso bloqueado pelo open_basedir
  4.     // trate aqui (fallback, log, etc.)
  5. } else {
  6.     foreach ($files as $file) {
  7.         // processa os arquivos
  8.     }
  9. }
Alternativa mais curta (quando não precisa diferenciar false de []):
  1. $files = glob($pattern);
  2. if (empty($files)) {
  3.     // vazio ([]) ou false
  4. } else {
  5.     foreach ($files as $file) {
  6.         // ...
  7.     }
  8. }

16) Outros comportamentos que podem gerar “efeitos colaterais” (menos comuns)

No PHP 8.2, algumas mudanças menores podem causar diferenças de resultado em códigos que dependem exatamente do valor retornado ou da ordem dos dados.

str_split("") agora retorna []

Isso pode afetar validações que esperam sempre pelo menos um item no array.
  1. var_dump(str_split(""));
  2. // PHP 8.2: array(0) { }
  3. // Antes:  array(1) { [0]=> string(0) "" }

var_export() e nomes de classes totalmente qualificados

A função var_export() passou a exportar nomes de classes usando o nome totalmente qualificado (incluindo \), principalmente quando a classe está dentro de um namespace.

Isso pode gerar diferenças em testes automatizados, snapshots ou comparações de string.

  1. namespace App\Model;

  2. class User {}

  3. echo var_export(new User(), true);
  4. // PHP 8.2: \App\Model\User::__set_state(array(
  5. // ...
  6. // ))

ksort() / krsort() com SORT_REGULAR e strings numéricas

Em alguns casos, a ordem dos elementos pode mudar quando as chaves do array são strings numéricas.
Por exemplo, "2" e "10", pois passam a seguir as regras atuais.

  1. $a = ["10" => "dez", "2" => "dois", "1" => "um"];

  2. ksort($a, SORT_REGULAR);
  3. var_dump(array_keys($a));

  4. krsort($a, SORT_REGULAR);
  5. var_dump(array_keys($a));

    • Related Articles

    • Como Gerar o Relatório para Migração do PHP

      Com o intuito de auxiliar os clientes que utilizam o Scriptcase em uma versão desatualizada do PHP (7.0 ou 7.3), montamos um roteiro para ajudar na migração dos projetos. Para que possamos ajudar na migração, é necessário o envio de um relatório ...
    • Adaptações de Compatibilidade para o PHP 8.2

      A partir da release 9.13.012, o Scriptcase passa a ser compatível com o PHP 8.2, tanto no ambiente de desenvolvimento quanto em produção. Ao atualizar o ambiente para o PHP 8.2, códigos personalizados (eventos, métodos e bibliotecas internas ou ...
    • Funções PHP necessárias para o ScriptCase

      No PHP, existem algumas funções essenciais para o funcionamento do Scriptcase. Em alguns servidores, esta funções são desabilitadas, isso faz com que o Scriptcase não funcione devidamente. Segue a lista das funções que não podem estar bloqueadas, ...
    • Criando a chave de Api do Google Maps

      Neste artigo veja como habilitar e obter a chave para utilização do Google Maps nas aplicações do Scriptcase. Acessando a Plataforma do google Maps 1. Acesse o link https://mapsplatform.google.com/ para criar sua chave. Será necessário realizar login ...
    • Configurando ambiente manualmente PHP 5.4 - Mac OS X

      Devemos seguir os passos abaixo para realizar a instalação do php 5.4 no Mac OS X ( Mavericks ) Execute no terminal: sudo curl -s http://php-osx.liip.ch/install.sh | bash -s 5.4 Local de instalação /usr/local/php5 Execute no terminal: sudo nano ...