Novidade do PHP 8.3
O PHP 8.3 ainda não foi lançado oficialmente, mas sua versão alfa está disponível. De acordo com a lista de tarefas de preparação , o PHP 8.3 será lançado em 23 de novembro de 2023 . Ele será testado por meio de três lançamentos alfa, três beta e seis candidatos a lançamento.
O que há de novo no PHP 8.3: novos recursos e mudanças
json_validate()
Este PHP RFC propõe a introdução de uma nova função, json_validate()
, para validar se uma string contém JSON válido.
As implementações atuais usam principalmente json_decode()
, que gera um ZVAL (objeto/array/etc.) durante a análise e usa memória e poder de processamento desnecessários.
A nova função usa o mesmo analisador JSON que existe no núcleo do PHP e é usado pelo json_decode()
, garantindo que o que é válido em json_validate()
também seja válido em json_decode()
.
Aqui estão alguns exemplos de como usar json_validate()
:
No PHP 8.2 e anteriores, usando json_decode()
:
$json = '{ "foo": "bar" }';
$decoded = json_decode($json);
if ($decoded === null && json_last_error() !== JSON_ERROR_NONE) {
// Invalid JSON.
} else {
// Valid JSON.
}
No PHP 8.3, usando json_validate()
:
$json = '{ "foo": "bar" }';
if (json_validate($json)) {
// Valid JSON.
} else {
// Invalid JSON.
}
Saiba mais: PHP RFC: json_validate
unserialize()
– Tratamento de erros aprimorado
A RFC propõe duas mudanças principais na função unserialize do PHP para aprimorar seu tratamento de erros.
O tratamento de erro atual em unserialize()
é inconsistente, pois pode emitir um E_NOTICE
, um E_WARNING
ou lançar um arbitrário , ou Exception
Error
dependendo de como a string de entrada está mal formada.
Isso dificulta o tratamento confiável de erros durante a desserialização.
A primeira proposta é introduzir uma nova exceção de wrapper, UnserializationFailedException
.
Sempre que um Throwable
for lançado durante a unserialize, isso Throwable
será agrupado em uma nova instância de UnserializationFailedException
.
Isso permite que os desenvolvedores usem um único catch(UnserializationFailedException $e)
para lidar com todos Throwable
os acontecimentos possíveis durante a desserialização.
O original Throwable
pode ser acessado por meio da propriedade $previous de UnserializationFailedException
, permitindo que o desenvolvedor aprenda sobre a causa real da falha de deserialização.
A segunda proposta é aumentar a severidade do reporte de erros no unserialize()
parser.
No estado atual, a desserialização pode falhar devido a um erro de sintaxe na string de entrada, números inteiros fora do intervalo e problemas semelhantes, que resultam em um E_NOTICE
ou E_WARNING
.
Este RFC propõe aumentar a gravidade desses avisos/avisos e, finalmente, fazer com que eles lancem o novo arquivo UnserializationFailedException
.
Antes das mudanças propostas, lidar com erros de desserialização em PHP poderia ser assim:
try {
set_error_handler(static function ($severity, $message, $file, $line) {
throw new \ErrorException($message, 0, $severity, $file, $line);
});
$result = unserialize($serialized);
} catch (\Throwable $e) {
// Falha na deserialização. Bloco catch opcional se o erro não deve ser tratado.
} finally {
restore_error_handler();
}
var_dump($result); // Faça algo com o $result.
// Não deve aparecer no 'tentar' para não 'capturar' erros não relacionados.
E vários casos típicos podem ser assim:
unserialize('foo'); // Notice: unserialize(): Error at offset 0 of 3 bytes in php-src/test.php on line 3
unserialize('i:12345678901234567890;'); // Warning: unserialize(): Numerical result out of range in php-src/test.php on line 4
unserialize('E:3:"foo";'); // Warning: unserialize(): Invalid enum name 'foo' (missing colon) in php-src/test.php on line 5
// Notice: unserialize(): Error at offset 0 of 10 bytes in php-src/test.php on line 5
Após as alterações propostas, o tratamento dos erros de deserialização no PHP ficaria da seguinte forma:
function unserialize(string $data, array $options = []): mixed
{
try {
// The existing unserialization logic happens here.
} catch (\Throwable $e) {
throw new \UnserializationFailedException(previous: $e);
}
}
E a implementação da nova exceção:
class UnserializationFailedException extends \Exception
{
}
O RFC foi parcialmente aceito para PHP 8.3.
Saiba mais: PHP RFC: Melhore o tratamento de erros unserialize()
Adições de randomizador
O RFC para PHP intitulado “Randomizer Additions” propõe três novos métodos e uma enumeração de acompanhamento para a \Random\Randomizer
classe.
O método getBytesFromString()
permite gerar uma string de um comprimento especificado usando bytes selecionados aleatoriamente de uma determinada string.
O getFloat()
método retorna um float entre um definido $min
e $max
, com os limites do intervalo sendo abertos ou fechados dependendo do valor do parâmetro $boundary
.
O método
nextFloat()
é equivalente a ->getFloat(0, 1, \Random\IntervalBoundary::ClosedOpen)
.
A enumeração IntervalBoundary
é usada para determinar a natureza dos limites do intervalo no método
getFloat()
Por exemplo, com o método getBytesFromString()
:
Antes:
$randomString = '';
$characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
$charactersLength = strlen($characters);
for ($i = 0; $i < 16; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
$randomDomain = $randomString . ".example.com";
Depois:
$randomizer = new \Random\Randomizer();
$randomDomain = $randomizer->getBytesFromString('abcdefghijklmnopqrstuvwxyz0123456789', 16) . ".example.com";
Saiba mais: PHP RFC: adições de randomizador
Busca constante de classe dinâmica
Este RFC propõe permitir que as constantes de classe sejam acessadas dinamicamente usando variáveis.
Em vez de acessar constantes de classe com um valor de string estático (por exemplo, ClassName::CONSTANT
), você pode usar uma variável contendo o nome da constante.
$constant = 'CONSTANT';
ClassName::{$constant}
Essa alteração facilitaria o acesso às constantes de classe de forma dinâmica e programática.
Saiba mais: PHP RFC: busca constante de classe dinâmica
Exceções de data/hora mais apropriadas
A RFC propõe introduzir exceções e erros específicos de extensão de data/hora no PHP, em vez dos avisos, erros e exceções mais genéricos usados atualmente.
Isso visa fornecer melhor especificidade e tratamento para exceções relacionadas a Data/Hora.
A proposta inclui várias exceções específicas, como DateInvalidTimeZoneException
, DateInvalidOperationException
, DateMalformedStringException
, DateMalformedIntervalStringException
, e outras.
Notavelmente, essa alteração afeta apenas o uso do estilo orientado a objeto de funções de data/hora, pois o uso do estilo procedural continuará a usar avisos e erros como atualmente.
Abaixo estão exemplos de como as novas exceções funcionam:
Antes da mudança:
Para criar um DateInterval
com uma string mal formada, a chamada da função retornaria um aviso e falso:
try {
$i = DateInterval::createFromDateString("foo");
} catch (Exception $e) {
echo $e::class, ': ', $e->getMessage(), "\n";
}
Para tentar subtrair uma especificação de tempo relativo não especial de um DateTimeImmutable
objeto, a chamada de função retornaria um aviso e null
:
$now = new DateTimeImmutable("2022-04-22 16:25:11 BST");
var_dump($now->sub($e));
Após a alteração:
Para criar um DateInterval
com uma string mal formada, a função agora lança um DateMalformedIntervalStringException
:
try {
$i = DateInterval::createFromDateString("foo");
} catch (DateMalformedIntervalStringException $e) {
echo $e::class, ': ', $e->getMessage(), "\n";
}
Para tentar subtrair uma especificação de tempo relativo não especial de um DateTimeImmutable
objeto, a função agora lança um DateInvalidOperationException
:
$now = new DateTimeImmutable("2022-04-22 16:25:11 BST");
try {
var_dump($now->sub($e));
} catch (DateInvalidOperationException $e) {
echo $e::class, ': ', $e->getMessage(), "\n";
}
Saiba mais: PHP RFC: exceções de data/hora mais apropriadas
Leia apenas as alterações
Este é um RFC de duas partes e somente a parte em que as propriedades somente leitura podem agora ser reinicializadas durante a clonagem foi aceita.
Esta proposta visa eliminar a limitação que impede que propriedades readonly sejam “deep-cloned”.
Ele permite que as propriedades somente leitura sejam reinicializadas durante a execução da chamada do método mágico __clone()
. Aqui está um exemplo dessa mudança:
Antes:
class Foo {
public function __construct(
public readonly DateTime $bar,
public readonly DateTime $baz
) {}
public function __clone()
{
$this->bar = clone $this->bar; // Doesn't work, an error is thrown.
}
}
Depois:
class Foo {
public function __construct(
public readonly DateTime $bar,
public readonly DateTime $baz
) {}
public function __clone()
{
$this->bar = clone $this->bar; // Works.
$this->cloneBaz();
}
private function cloneBaz()
{
unset($this->baz); // Also works.
}
}
$foo = new Foo(new DateTime(), new DateTime());
$foo2 = clone $foo;
// No error, Foo2::$bar is cloned deeply, while Foo2::$baz becomes uninitialized.
Saiba mais: PHP RFC: Alterações somente leitura
Saner array_sum() e array_product()
Este RFC introduz alterações no comportamento das funções array_sum()
e array_product()
para torná-los mais consistentes com suas implementações de userland usando array_reduce()
.
Atualmente, array_sum()
e array_product()
pula entradas de array ou objeto, enquanto suas implementações de userland usando array_reduce() lançam um arquivo TypeError
.
As mudanças propostas incluem:
- Usando o mesmo comportamento para
array_sum()
earray_product()
como asarray_reduce()
variantes. - Emitindo um
E_WARNING
para tipos incompatíveis. - Objetos de suporte com elenco numérico para serem adicionados/multiplicados.
Saiba mais: PHP RFC: Saner array_(sum|product)()
PHP RFC: Constantes de classe digitadas
As constantes de classe digitadas estão finalmente chegando no PHP 8.3!
Eles ajudarão a reduzir erros e confusões decorrentes de classes filhas substituindo as constantes da classe pai.
As constantes de classe digitadas podem ser declaradas em classes, interfaces, características e enums.
Pontos chave:
- As declarações de tipo constante de classe suportam todas as declarações de tipo do PHP, exceto void, callable e never.
- O modo Strict_types não afeta o comportamento, pois as verificações de tipo são sempre executadas no modo estrito.
- As constantes de classe são covariantes, o que significa que seus tipos não podem ser ampliados durante a herança.
- Os valores constantes devem corresponder ao tipo da constante de classe, com a exceção de que as constantes de classe float também podem aceitar valores inteiros.
- ReflectionClassConstant é estendido com dois métodos: getType() e hasType().
Como você pode imaginar, as constantes digitadas são super fáceis de usar, assim como as propriedades tipadas:
interface Foo {
public const string BAR = 'baz';
}
class Bar extends Foo {
// Doesn't work anymore! You cannot change the
// type and assign a value of another type.
public const array BAR = ['foo', 'bar', 'baz'];
// OK.
public const string BAR = 'foo';
}
Saiba mais: PHP RFC: Constantes de classe digitadas
Inicializadores de variáveis estáticas arbitrárias
A RFC propõe uma alteração que permitiria ao inicializador de variáveis estáticas conter expressões arbitrárias, em vez de apenas expressões constantes.
Isso torna a linguagem mais flexível e menos confusa para os usuários. Por exemplo, antes dessa mudança, uma variável estática só podia ser inicializada com uma constante:
function foo() {
static $i = 1;
echo $i++, "\n";
}
foo();
foo();
foo();
Isso produziria:
1
2
3
Com a alteração proposta, uma variável estática pode ser inicializada com uma chamada de função:
function bar() {
echo "bar() called\n";
return 1;
}
function foo() {
static $i = bar();
echo $i++, "\n";
}
foo();
foo();
foo();
A proposta também introduz várias mudanças na semântica da inicialização de variáveis estáticas, incluindo o tratamento de exceções durante a inicialização, a ordem das operações quando destruidores estão envolvidos e o tratamento da recursão durante a inicialização.
Porém, a declaração novamente de variáveis estáticas não seria permitida e isso altera a forma como ReflectionFunction::getStaticVariables()
funciona com variáveis estáticas.
Saiba mais: PHP RFC: inicializadores de variáveis estáticas arbitrárias
E lembrando que a SOLOWEB além de oferecer Hospedagem de Sites, Servidores Dedicados, Servidores VPS com o menor custo do Brasil, também desenvolve soluções de software e realiza gerenciamento e monitoramento de servidores para sua empresa, faça uma cotação sem custo, acesse: www.soloweb.com.br