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? 🤔

Made with Slides.com