PHP 8.0 🐘

Uma nova versão, uma nova era

PHP 8.0 🐘

calendário de lançamentos (2020)

 

 

Junho 25 ~ Julho 23 - Alphas (1, 2, 3)

Agosto 4 ~ Congelamento de Funcionalidades (F.F ❄️)

Agosto 6 ~ Setembro 17 - Betas (1, 2, 3, 4)

Outubro 1 ~ Novembro 12 - Candidatos a Lançamento (1, 2, 3, 4, 5)

26 Novembro - Lançamento Geral (G.A. 🔥)

PHP 8.0 🐘

VERSÕES SUPORTADAS EM 2021

 

PHP 7.2 - Não será suportada

PHP 7.3 - Apenas Correções de Segurança

PHP 7.4 - Suporte Ativo

PHP 8.0 - Suporte Ativo

#php80

  • Gabriel Caruso 🇧🇷 ~> 🇳🇱

 

  • Desenvolvedor Backend @ SurveyMonkey 

 

  • Contribuidor OSS 👨🏻‍💻

#php80

  • Melhorias de Performance
  • Algumas das novas funcionalidades
  • Algumas mudanças
  • Quebras de Compatibilidade
  • Mudanças Internas
  • Por detrás das câmeras do desenvolvimento do PHP 8.0

Agenda

#php80

Melhorias de Performance 📈

JIT (Just-in-time)

- Não espere melhorias de performance como PHP 5.6 ~> PHP 7.0

 

- Processos Pesados irão se beneficar disto, não simples and rápidas APIs

Palestras sobre JIT

- https://youtu.be/g3RPYtwP1jk: Benoit Jacquemont (em Francês)

- https://youtu.be/JZAs1YTcRHM: Nickolas da Silva (em Português)

- https://youtu.be/5H77TnoLLcU: Nikita Popov (em Inglês)

- https://youtu.be/7UOWus-5yxg: Dmitry Stogov (em Russo)

 

Amanhã (05/12) - Ricardo Coelho com "JIT - E eu com isso?"

#php80

Instâncias GRAVITON2 ARM64 da AWS 

- Desde o PHP 7.4, a AWS tem ajudado o PHP com código melhorando a performance

 

- Blog post com todas as mudanças e benchmarks

 

Funcionalidades 🔥

`match` Control Structure

`mixed` type

`?->` Operator

Constructor Property Promotion

`Stringable` Interface

Attributes

New `string_*` functions

Weak Maps

`static` return type

Validation for abstract trait methods

New `fdiv` function

Trailing commas in more places

DOM Living Standard APIs

New `preg_last_error_msg` function

Cryptographic Message Syntax (CMS) (RFC 5652) support

Array sorting functions are now stable

Union Types

Named Arguments

`PhpToken` class

New `get_resource_id` function

PHP 8.0 tem muitas funcionalidades

`match` Control Structure

`?->` Operator

Attributes

Union Types

Named Arguments

mas vamos focar nestas

Union types

<?php declare(strict_types=1);

class Number
{
    /** @var int|float $number */
    private $number;
 
    /** @param int|float $number */
    public function setNumber($number)
    {
        $this->number = $number;
    }
 
    /** @return int|float */
    public function getNumber()
    {
        return $this->number;
    }
}

Union types

<?php declare(strict_types=1);

class Number
{
    /** @var int|float $number */
    private $number;
 
    /** @param int|float $number */
    public function setNumber($number)
    {
        $this->number = $number;
    }
 
    /** @return int|float */
    public function getNumber()
    {
        return $this->number;
    }
}

$number = new Number();

$number->setNumber('string');

echo $number->getNumber(); // 'string'

Union types

<?php declare(strict_types=1);

class Number
{
    /** @var int|float $number */
    private $number;
 
    /** @param int|float $number */
    public function setNumber($number)
    {
    	if (!is_int($number) && !is_float($number)) {
            throw new \InvalidArgumentException(
            	sprintf('Argument $number should be either an integer or float, %s given', gettype($number))
            );
        }
        
        $this->number = $number;
    }
 
    /** @return int|float */
    public function getNumber()
    {
        return $this->number;
    }
}

$number = new Number();

$number->setNumber('string'); // InvalidArgumentException: Argument $number should be either an integer or float, string given

Union types

<?php declare(strict_types=1);

class Number
{
    private int|float $number;
 
    public function setNumber(int|float $number): void
    {
        $this->number = $number;
    }
 
    public function getNumber(): int|float
    {
        return $this->number;
    }
}

Union types

<?php declare(strict_types=1);

class Number
{
    private int|float $number;
 
    public function setNumber(int|float $number): void
    {
        $this->number = $number;
    }
 
    public function getNumber(): int|float
    {
        return $this->number;
    }
}

$number = new Number();

$number->setNumber('string'); // Number::setNumber(): Argument #1 ($number) must be of type int|float, string given
<?php declare(strict_types=1);

class Collection
{
    private array $items;
 
    public function setItem(string $index, array|bool|callable|int|float|null|object|string $value): void
    {
        $this->items[$index] = $value;
    }
 
    public function getItem(string $index): array|bool|callable|int|float|null|object|string
    {
        return $this->items[$index];
    }
}

Union types

mixed type

<?php declare(strict_types=1);

class Collection
{
    private array $items;
 
    public function setItem(string $index, mixed $value): void
    {
        $this->items[$index] = $value;
    }
 
    public function getItem(string $index): mixed
    {
        return $this->items[$index];
    }
}

match

<?php declare(strict_types=1);

$value = '2';

switch ($value) {
    case 0:
        $result = 'Foo';
        break;
    case 1:
        $result = 'Bar';
        break;
    case 2:
        $result = 'Baz';
        break;
}
 
echo $result; // 'Baz'

match

<?php declare(strict_types=1);

$value = '3';

switch ($value) {
    case 0:
        $result = 'Foo';
        break;
    case 1:
        $result = 'Bar';
        break;
    case 2:
        $result = 'Baz';
        break;
}
 
echo $result; // Warning: Undefined variable $result

match

<?php declare(strict_types=1);

$value = '3';

switch ($value) {
    case 0:
        $result = 'Foo';
        break;
    case 1:
        $result = 'Bar';
        break;
    case 2:
        $result = 'Baz';
        break;
    default:
        throw new \InvalidArgumentException(sprintf('No `case` for $value %s', $value));
}
 
echo $result; // InvalidArgumentException: No `case` for $value 3

match

<?php declare(strict_types=1);

$value = 2;

echo match ($value) {
    0 => 'Foo',
    1 => 'Bar',
    2 => 'Baz',
}; // Baz

match

<?php declare(strict_types=1);

$value = 3;

echo match ($value) {
    0 => 'Foo',
    1 => 'Bar',
    2 => 'Baz',
}; // UnhandledMatchError: Unhandled match value of type int

Nullsafe operator

<?php declare(strict_types=1);

$neighborhood = $address->getNeighborhood(); // returns either NULL or a Neighborhood object

$neighborhoodName = $neighborhood ? $neighborhood->getName() : null;

if ($neighborhoodName !== null) {
    // do something with $neighborhoodName
}

Nullsafe operator

<?php declare(strict_types=1);

$neighborhoodName = $address->getNeighborhood()?->getName();

if ($neighborhoodName !== null) {
    // do something with $neighborhoodName
}

named arguments

<?php declare(strict_types=1);

$items = [
    1, 2, 'foo',
];

$integers = array_filter($items, fn (mixed $item): bool => is_int($item));

var_dump($integers); // [1, 2]

named arguments

<?php declare(strict_types=1);

var_dump(
    array_fill(2, 3, 'PHP')
);

named arguments

<?php declare(strict_types=1);

var_dump(
    array_fill(2, 3, 'PHP')
); // [2 => 'PHP', 3 => 'PHP', 4 => 'PHP']

named arguments

<?php declare(strict_types=1);

var_dump(
    array_fill(start_key: 2, count: 3, value: 'PHP')
); // [2 => 'PHP', 3 => 'PHP', 4 => 'PHP']

named arguments

<?php declare(strict_types=1);

class Person
{
    public function __construct(string $name, int $age)
    {
        // ...
    }
}

new Person(name: 'Gabriel Caruso', age: 22);

named arguments

<?php declare(strict_types=1);

interface Person
{
    public function setName(string $name);
}
 
class MyPerson implements Person
{
    public function setName(string $fullName) {}
}
 
$person = (new MyPerson)->setName('Gabriel Caruso'); // fullName or name?

named arguments

<?php declare(strict_types=1);

interface Person
{
    public function setName(string $name);
}
 
class MyPerson implements Person
{
    public function setName(string $fullName) {}
}
 
$person = (new MyPerson)->setName(fullName: 'Gabriel Caruso'); // Named Arguments allows renaming

named arguments

<?php declare(strict_types=1);

class User
{
    public function __construct(
        bool $admin,
        bool $active,
        ?array $rules = [],
    ) {
        // Construct the object...
    }
}

$user = new User(true, false, null);

named arguments

<?php declare(strict_types=1);

class User
{
    public function __construct(
        bool $admin,
        bool $active,
        ?array $rules = [],
    ) {
        // Construct the object...
    }
}

$user = new User(
    admin: true,
    active: false,
    rules: null
);

named arguments

<?php declare(strict_types=1);

function randomOrder(int $arg1, string $arg2, float $arg3) {}

randomOrder(arg2: 'PHP', arg3: 8.0, arg1: 1);

function optionals(string $arg1 = 'default', int $arg2 = 1) {}

optionals(arg2: 3);

function skipping(int $arg1, string $arg2, float $arg3) {}

skipping(1, 'PHP', arg3: 8.0); // This is allowed

skipping(1, arg2: 'PHP', 8.0); // Fatal error: Cannot use positional argument after named argument

attributes

<?php declare(strict_types=1);

/** @Entity */
final class User
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     */
    private int $id;

    /** @ORM\Column() */
    private string $name;
}

Annotations

Elas são usadas para documentar o seu código

attributes

Atributos mudam o comportamento do seu código. Pense em "meta programação"

attributes

<?php declare(strict_types=1);

#[Entity]
final class User
{
    #[ORM\Id()]
    #[ORM\Column(type="integer")]
    private int $id;

    #[ORM\Column()]
    private string $name;
}

vantagens de ter attributes nativos no php

- Muitas bibliotecas, projetos e framework tem suas próprias implementações. Isso será centralizado agora

- Caching, otimizações e tudo do bom e do melhor que o PHP tem a oferecer

- Annotations serão usadas para documentação

um ponto super importante sobre o ATTRIBUTES no php 8.0 ⚠️

- Não converta Annotations para Attributes antes de checar se a library, ou framework, tem suporte a eles

 

- Dê uma lida na RFC, na parte de "Reflection" para entender como adicionar support à Attributes

mudanças 🔩

throw agora é uma expressão

<?php declare(strict_types=1);

$callable = fn() => throw new Exception(); // this was not possible before PHP 8.0

$value = $nullableValue ?? throw new InvalidArgumentException(); // `throw` is now considered an expression

VARIÁVEL no catch não é mais obrigatória

<?php declare(strict_types=1);

try {
    $this->login($user);
} catch (PermissionException) { // $exception variable is no longer required
    throw AuthenticationException::failedLogin();
}

constante mágica ::class agora supporta objetos

<?php declare(strict_types=1);

namespace Foo\Bar {
    class Baz {}
    
    $baz = new \Foo\Bar\Baz();

    var_dump(
        $baz::class, // "Foo\Bar\Baz"
    );
}
<?php declare(strict_types=1);

namespace Foo\Bar {
    class Baz {}
    
    $baz = new \Foo\Bar\Baz();

    var_dump(
        $baz::class, // "Foo\Bar\Baz"
        get_class($baz) // "Foo\Bar\Baz"
    );
}

constante mágica ::class agora supporta objetos

erros em PDO agora são PDO::ERRMODE_EXCEPTION

- Era `PDO::ERRMODE_SILENT`, e agora é `PDO::ERRMODE_EXCEPTION`

 

- Problemas comuns como consultas `SQL` com errors de sintaxe serão expostos pela extensão

#php80

ARGUMENTOS OPCIONAIS SEGUIDOS DE REQUERIDOS ESTÁ DEPRECATED

#phpcs2020

<?php declare(strict_types=1);

function test(string $param = '', $param2) {
    // do something with $param and $param2
}

// Deprecated: Required parameter $param2 follows optional parameter $param

Quebras de Compatibilidade 🚨

REMOÇÃO DAS FUNCIONALIDADES DO 7.x QUE ESTAVAM deprecated 

- Declaração de constantes não case-sensitive

- Construtores PHP 4

- Chamadas estáticas à métodos não estáticos

- Alias para algumas funções MBString

- Cast `(unset)`

- Dê uma lida no PR para a lista completa...

MÉTODOS MÁGICAS TERÃO SUAS ASSINATURAS CHECADAS

<?php declare(strict_types=1);

class Foo
{
    public function __toString(): bool
    {
        return true;
    }
}

// Declaration of Foo::__toString(): bool must be compatible with Stringable::__toString(): string

checagens mais estritas para operações aritméticas/bitwise

<?php declare(strict_types=1);

$result = [] % [42]; // It will throw a "TypeError: Unsupported operand types"

$array = [2, 3];
$array++; // It will throw a "TypeError: Cannot increment array"

$object = new stdClass();
$object++; // It will throw a "TypeError: Cannot increment stdClass"

COMPARAÇÕES QUE FAZEM SENTIDO ENTRE STRINGS E NÚMEROS

<?php declare(strict_types=1);

var_dump(
    0 == "0", // continua `true`
    0 == "0.0", // continua `true`
    0 == "foo", // era `true`, agora é `false`
    0 == "", // era `true`, agora é `false`
    42 == "   42", // continua `true`
    42 == "42foo", // era `true`, agora é `false`
);

Mudanças Internas 👀

melhorias para a API de REFLECTION

<?php declare(strict_types=1);

$reflectionFunction = new ReflectionFunction('array_filter');

foreach ($reflectionFunction->getParameters() as $parameter) {
    echo sprintf('Parameter $%s, type %s', $parameter->getName(), $parameter->getType() ?? '*NO TYPE DEFINED*') . PHP_EOL; 
}

echo 'array_filter return type: ' . $reflectionFunction->getReturnType() ?? '*NO TYPE DEFINED*';
<?php declare(strict_types=1);

$reflectionFunction = new ReflectionFunction('array_filter');

foreach ($reflectionFunction->getParameters() as $parameter) {
    echo sprintf('Parameter $%s, type %s', $parameter->getName(), $parameter->getType() ?? '*NO TYPE DEFINED*') . PHP_EOL; 
}

echo 'array_filter return type: ' . $reflectionFunction->getReturnType() ?? '*NO TYPE DEFINED*';

// Before PHP 8.0

// Parameter $arg, type *NO TYPE DEFINED*
// Parameter $callback, type *NO TYPE DEFINED*
// Parameter $use_keys, type *NO TYPE DEFINED*
// array_filter return type: *NO TYPE DEFINED*

melhorias para a API de REFLECTION

<?php declare(strict_types=1);

$reflectionFunction = new ReflectionFunction('array_filter');

foreach ($reflectionFunction->getParameters() as $parameter) {
    echo sprintf('Parameter $%s, type %s', $parameter->getName(), $parameter->getType() ?? '*NO TYPE DEFINED*') . PHP_EOL; 
}

echo 'array_filter return type: ' . $reflectionFunction->getReturnType() ?? '*NO TYPE DEFINED*';

// After PHP 8.0

// Parameter $array, type array
// Parameter $callback, type ?callable
// Parameter $use_keys, type int
// array_filter return type: array

melhorias para a API de REFLECTION

QUAIS PROJETOS IRÃO SE BENEFICAR DESSAS MELHORIAS?

  • phpstan/phpstan

  • vimeo/psalm

  • roave/better-reflection

  • jetbrains/phpstorm-stubs

mudanças a alguns PHP INI

- Padrão do `error_reporting` agora é `E_ALL`. Anteriormente não incluia `E_NOTICE` e `E_DEPRECATED`

- `zend.exception_string_param_max_len` agora é configurável, melhorando `Throwable::getTraceAsString()`

- `assert.exception` agora é `true`, lançando uma exceção ao invés de um Warning

Por detrás das câmeras do desenvolvimento do PHP 8.0 🎥

quem está por trás do php 8.0?

gerentes da versão

Gabriel Caruso (sua primeira vez)

Sara Golemon (gerente do PHP 7.2)

- Responsáveis por tomarem conta e coordernar todos os lançamentos desde o Alpha 1 até G.A

- Responsáveis por versões patch a cada 4 semanas após G.A.

- (Não oficial, mas) Os gerentes são aqueles que vão à eventos, meetups, escrevem blog posts sobre a nova versão para espalhar as novidades na comunidade

gerentes da versão

contribuidores

Dmitry Stogov (JIT)

Nikita Popov (JetBrains)

Christoph M. Becker (Microsoft)

contribuidores

Matteo Beccati  (PDO/Postgres)

Tyson Andre (Phan)

contribuidores

novos contribuidores

novos contribuidores

Benjamin Eberlei (Doctrine)

Nicolas Grekas (Symfony)

contribuidores famosos

PHP 8.0 EM ALGUMAS PALAVRAS?

FOI UMA VERSÃO EM QUE A COMUNIDADE AJUDOU BASTANTE A DESENVOLVER

será fácil migrar para o php 8.0 vindo de verSões php 7.x?

sim, e se você usa uma ferramenta de análise estática no seu código, será ainda mais fácil

QUER ajudar o php 8.0?

 

Teste, e reporte bugs no https://bugs.php.net

 

COMPARTILHE: HTTPS://PHP.NET/RELEASES/8.0

ESSA PALESTRA FOI SÓ A PONTA DO ICEBERG 🗻

VOCÊ PODE CONFERIR TODAS AS REFERÊNCIAS PARA ESSA PALESTRA, COM blog posts, VÍDEOS NO youtube E MUITO MAIS.

Muito Obrigado ♥️

Por favor, deixe feedback para está palestra 👉🏻

Perguntas? 🤔

PHP 8.0: Uma nova versão, uma nova era

By Gabriel Caruso (Caruso)

PHP 8.0: Uma nova versão, uma nova era

PHP 8.0 está chegando e você deve estar se perguntando: quais são as novas funcionalidades? Será que eles corrigiram aqueles bugs estranhos? Será que a minha aplicação ficará mais rápida? Consigo dar suporte ao PHP 7 e ao PHP 8 ao mesmo tempo na minha biblioteca ou framework? Nesta palestra, vamos passar um tempo vendo o que há de novo no PHP 8.0, o que mudou internamente e externamente na linguagem, tanto novas funcionalidades quanto mudanças de comportamento. Como um dos Release Managers, Gabriel Caruso irá te contar tudo sobre, dando todos os recursos necessários para você se atualizar sobre essa nova versão major do PHP, programada para ser lançada em Novembro de 2020.

  • 1,781