Upgrade to Pro — share decks privately, control downloads, hide ads and more …

O Que Há de Novo no PHP 8.0 e 8.1?

O Que Há de Novo no PHP 8.0 e 8.1?

O PHP tem evoluído constantemente nos últimos anos e hoje em dia conta com um robusto ecossistema de ferramentas e funcionalidades. E, em breve, será lançado o PHP 8.1. Ela será uma das releases com um grande número de funcionalidades. Nesta apresentação falaremos sobre as novidades do PHP 8.0 e 8.1 como named arguments, attributes, constructor property promotion, match expressions, enums, array unpacking com chaves em string, readonly properties entre outras novidades.

Marcel dos Santos

November 04, 2021
Tweet

More Decks by Marcel dos Santos

Other Decks in Programming

Transcript

  1. Marcel Gonçalves dos Santos
    @marcelgsantos
    php 8.0
    o que há de novo
    ?
    8.1
    no
    e

    View Slide

  2. pensandonaweb.com.br
    desenvolvedor web full-stack
    Marcel Gonçalves dos Santos
    @marcelgsantos

    View Slide

  3. @phpsp
    phpsp.org.br

    View Slide

  4. Interaja nas mídias sociais!


    - fale sobre o evento, palestrantes e conteúdo


    - tire fotos do evento e publique

    - interaja com outros participantes do evento


    - tire dúvidas ou dê feedbacks para os palestrantes

    - utilize as hashtags#php80 e #php81

    View Slide

  5. O início!

    View Slide

  6. o PHP existe há mais de 20 anos e passou
    por várias "revoluções"

    View Slide

  7. na versão 5.3 o PHP incluiu o suporte para
    namespaces, funções lambda e closures

    View Slide

  8. a criação do PHP-FIG permitiu a de
    fi
    nição de
    padrões pela comunidade

    View Slide

  9. o Composer causou uma transformação na
    forma como bibliotecas são distribuídas e
    como aplicações PHP são desenvolvidas

    View Slide

  10. na versão 7.0
    fi
    cou de 2 a 3 vezes mais
    rápido e inúmeras funcionalidades foram
    adicionadas ao core da linguagem

    View Slide

  11. na versão 7.4 foram introduzidas funcionali-
    dades muito solicitadas como propriedades
    tipadas, arrow functions e spread operator

    View Slide

  12. o PHP como plataforma encontra-se
    mais maduro e robusto

    View Slide

  13. C
    om
    pos
    e
    , L
    ar
    avel, Symf
    on
    y, Laminas, Slim, Sil
    er
    , CakePHP
    , Yii,
    CodeIgnit
    e
    , Pr
    oo
    ph, Doc
    tr
    ine, Guzzle, Respect, PHP League,
    M
    on
    ol
    og, PHP-DI, FastR
    ou
    te, Psl, PHP-DS, Symf
    on
    y C
    om
    p
    on
    ents,
    Ramsey Uuid, Email Validat
    o
    , C
    ar
    b
    on
    , Flysystem, CLImate, Psysh,
    Twig, Fak
    e
    , Int
    er
    venti
    on
    Image, Ass
    er
    t, Depl
    oyer
    , PHPMail
    e
    ,
    Magento, W
    or
    dPress, Drupal, J
    oo
    mla, Sylius, OpenC
    ar
    t,
    W
    oo
    C
    om
    m
    er
    ce, PhpSt
    or
    m, Sw
    oo
    le, ReactPHP
    , Amp, Rev
    ol
    t PHP
    , Hyp
    er
    f,
    Octane, Bref, Vap
    o
    , XDebug, phpdbg, PHPStan, Psalm, Phan,
    PHPUnit, Codecepti
    on
    , Pest, Infecti
    on
    PHP
    , PHPSpec, Pr
    op
    hecy,
    Mock
    er
    y, Behat, PHP CodeSniff
    e
    , PHP CS F
    ixer
    , PHPMD, PHPCPD,
    GrumPHP
    , CaptainH
    oo
    k, Dep
    tr
    ac, Rect
    or
    , phpDocument
    o
    , Safe-PHP

    View Slide

  14. mas sempre existe espaço para melhorar!

    View Slide

  15. a próxima grande novidade do PHP é o
    lançamento da versão 8.1, uma release
    com muitas novidades

    View Slide

  16. Uma breve revisão


    sobre PHP 7.4!

    View Slide

  17. Typed properties ou
    propriedades tipadas

    View Slide

  18. as typed properties ou propriedades
    tipadas era uma das funcionalidades mais
    esperadas do PHP 7.4

    View Slide

  19. o PHP teve uma enorme evolução no seu
    sistema de tipos com o passar do tempo

    View Slide

  20. utilizavam-se docblocks e métodos getters e
    setters para a garantia de tipos

    View Slide

  21. isso fazia com que, para ter essa garantia,
    houvesse um boilerplate desnecessário de
    código

    View Slide

  22. / /
    code with unnecessary boilerplate to enforce type contracts


    class User {


    /** @var int $id
    * /

    private $id;


    /** @var string $name
    * /

    private $name;


    public function
    _ _
    construct(int $id, string $name) {


    $this
    - >
    id = $id;


    $this
    - >
    name = $name;


    }


    public function getId()
    :
    int {


    return $this
    - >
    id;


    }


    / /
    setId, getName and setName implementation
    . . .

    }

    View Slide

  23. / /
    more concise code with same type contracts


    class User {


    public int $id;


    public string $name;




    public function
    _ _
    construct(int $id, string $name) {


    $this
    - >
    id = $id;


    $this
    - >
    name = $name;


    }


    }

    View Slide

  24. as propriedades tipadas permitem a
    garantia de tipos em tempo de execução

    View Slide

  25. se uma propriedade tipada não tiver
    um valor padrão ela será considerada não
    inicializada

    View Slide

  26. / /
    uninitialized properties and default null


    class User {


    public $id;


    public $name;


    }


    $user = new User;


    var_dump($user);


    / /
    class User#1 (2) {


    / /
    public $id
    = >
    NULL


    / /
    public $name
    = >
    NULL


    / /
    }

    View Slide

  27. / /
    uninitialized properties and no null default


    class User {


    public int $id;
    / /
    no null default


    public ?string $name;
    / /
    also no null default


    }


    $user = new User;


    var_dump($user);


    / /
    object(User)#1 (0) {


    / /
    ["id"]
    = >
    uninitialized(int)


    / /
    ["name"]
    = >
    uninitialized(?string)


    / /
    }

    View Slide

  28. ao tentar fazer a leitura de uma propriedade
    não inicializada será lançado um erro do tipo
    TypeError

    View Slide

  29. / /
    try to access a uninitialized property


    class User {


    public int $id;


    public string $name;


    }


    $user = new User;


    echo $user
    - >
    id;


    / /
    Uncaught Error: Typed property User
    : :
    $id must

    / /
    not be accessed before initialization

    View Slide

  30. Arrow functions

    View Slide

  31. as funções anônimas no PHP são bastante
    verbosas, principalmente quando vamos
    realizar uma operação simples

    View Slide

  32. isso ocorre por causa do boilerplate sintático

    e a necessidade de importar as variáveis que
    serão utilizadas no escopo interno da função

    View Slide

  33. / /
    anonymous function (more verbose)


    $add = function ($x, $y) {


    return $x + $y;


    };

    View Slide

  34. a funcionalidade de arrow functions do


    PHP 7.4 torna mais concisa a sintaxe para
    esse padrão

    View Slide

  35. / /
    anonymous function (less verbose)


    $add = fn ($x, $y)
    = >
    $x + $y;

    View Slide

  36. a sintaxe de uma arrow function é a
    seguinte: fn(parameter_list) => expression

    View Slide

  37. ao utilizar uma variável de
    fi
    nida no escopo
    externo ela será passada de forma implícita
    para a expressão

    View Slide

  38. / /
    variable in parent scope is captured
    -
    by
    -
    value

    $y = 1;




    $inc1 = fn($x)
    = >
    $x + $y;




    $inc2 = function ($x) use ($y) {


    return $x + $y;


    };

    View Slide

  39. as arrow function podem ser utilizadas
    inúmeros casos do dia-a-dia

    View Slide

  40. / /
    arrow functions help reducing code boilerplate

    / /
    (without arrow functions)


    $result = Collection
    : :
    from([1, 2])


    - >
    map(function ($v) {


    return $v * 2;


    })


    - >
    reduce(function ($tmp, $v) {


    return $tmp + $v;


    }, 0);


    echo $result;
    / /
    6

    View Slide

  41. / /
    arrow functions help reducing code boilerplate


    / /
    (with arrow functions)

    $result = Collection
    : :
    from([1, 2])


    - >
    map(fn($v)
    = >
    $v * 2)


    - >
    reduce(fn($tmp, $v)
    = >
    $tmp + $v, 0);




    echo $result;
    / /
    6

    View Slide

  42. Spread operator


    em arrays

    View Slide

  43. o PHP possui o suporte ao argument
    unpacking desde a versão 5.6 da linguagem

    View Slide

  44. a funcionalidade permite o "desempacota-
    mento" de um array (ou um Traversable) em
    uma lista de argumentos utilizando o spread
    operator

    View Slide

  45. function sum($a, $b) {


    return $a + $b;


    }


    / /
    using spread operator (
    . . .
    ) to unpacking


    / /
    an array as an argument list


    $numbers = [3, 5];


    echo sum(
    . . .
    $numbers);
    / /
    8

    View Slide

  46. a utilização do spread operator não era
    permitido na de
    fi
    nição de arrays a partir de
    outro array

    View Slide

  47. / /
    using spread operator to def
    i
    ne a new array


    / /
    from another is not supported


    $someNumbers = [2, 3, 4];


    $numbers = [1,
    . . .
    $someNumbers, 5];


    print_r($numbers);

    / /
    PHP Parse error: syntax error, unexpected '
    . . .
    '

    / /
    (T_ELLIPSIS), expecting ']'

    View Slide

  48. a nova funcionalidade permite a utilização
    do spread operator (...) na de
    fi
    nição de um
    array através do unpacking dos valores de
    outro array ou Traversable

    View Slide

  49. / /
    using spread operator to def
    i
    ne an array from another


    $someNames = ['Bob', 'Carol'];


    $names = ['Alice',
    . . .
    $someNames, 'Daniel', 'Elisa'];


    print_r($names);


    / /
    ['Alice', 'Bob', 'Carol', 'Daniel', 'Elisa'];

    View Slide

  50. essa funcionalidade só está disponível para
    arrays com chaves numéricas (para manter
    consistência com o argument unpacking)

    View Slide

  51. Numeric literal

    separator

    View Slide

  52. ei, você consegue identi
    fi
    car que número é
    esse?

    View Slide

  53. 1000000000;

    View Slide

  54. é um bilhão, 100 milhões ou 10 bilhões?

    View Slide

  55. Difícil, né?!

    View Slide

  56. o olho de um ser humano não é otimizado
    para olhar e decodi
    fi
    car rapidamente uma
    sequências de dígitos

    View Slide

  57. e esse valor?

    View Slide

  58. $discount = 13500;

    View Slide

  59. é 13.500 ou 135 porque está em centavos?

    View Slide

  60. a nova funcionalidade numeric literal
    separator permite usar um separador visual
    para ajudar a melhorar a legibilidade do
    código e transmitir informações adicionais

    View Slide

  61. / /
    using numeric literal separator


    $threshold = 1_000_000_000;
    / /
    a billion


    $testValue = 100_925_284.88;
    / /
    scale is hundreds of millions


    $discount = 135_00;
    / /
    $135, stored as cents

    View Slide

  62. adicionar o underscore entre dois dígitos
    não alterará o seu valor

    View Slide

  63. / /
    adding undescore doesn't change the value


    var_dump(1_000_000);
    / /
    int(1000000)

    View Slide

  64. PHP 8.0

    View Slide

  65. Named arguments

    View Slide

  66. até o PHP 7.4 os argumentos só podiam ser
    passados de forma posicional

    View Slide

  67. a partir do PHP 8.0 é possível passar os
    argumentos de forma nomeada

    View Slide

  68. os argumentos nomeados permitem passar
    os argumentos para uma função com base
    no nome do parâmetro em vez da posição
    do parâmetro

    View Slide

  69. os benefícios de usar argumentos nomeados
    são:


    -o argumento é auto-explicativo


    -pode ser usado em qualquer posição


    -pode omitir valores padrões

    View Slide

  70. function greet(string $gretting, string $name, int $number = 1)
    :
    void


    {


    echo "$gretting, $name" . str_repeat('!', $number) . PHP_EOL;


    }


    / /
    using positional and named arguments


    greet("Hello", "Alice");
    / /
    Hello Alice!


    greet(gretting: "Hello", name: "Bob");
    / /
    Hello Bob!


    / /
    using of out
    -
    of
    -
    order named arguments


    greet("Hello", name: "Carol");
    / /
    Hello Carol!


    greet(name: "Dave", gretting: "Hello", number: 5);
    / /
    Hello, Dave!!!!!

    View Slide

  71. Attributes

    View Slide

  72. os attributes permitem adicionar meta-
    informações a elementos do código como
    classes, propriedades, métodos, funções,
    parâmetros e constantes

    View Slide

  73. eles permitem de
    fi
    nir diretivas de
    con
    fi
    guração diretamente no código

    View Slide

  74. conceitos similares existem em outras
    linguagens como annotations em Java,
    attributes em C#, Rust e Hack e decorators
    em Python e JavaScript

    View Slide

  75. os attributes ou annotations eram feitos
    com docblock e utilizam bibliotecas como
    Doctrine Annotations

    View Slide

  76. / /
    using docblock annotations in order to mapping


    / /
    an entity to database table


    class User


    {


    /** @Column(type="int")
    * /

    private int $id;


    /** @Column(type="string", length=100)
    * /

    private int $name;


    }

    View Slide

  77. agora, como parte da linguagem, os
    attributes podem ter a sintaxe veri
    fi
    cada

    por linters, ferramentas de análise

    estática e IDEs

    View Slide

  78. outra vantagem é não precisar de uma
    biblioteca externa para realizar o parsing de
    docblocks para obter as annotations

    View Slide

  79. / /
    using annotations with built
    -
    in attributes


    class User


    {

    # [
    Column(type: 'integer')]


    private int $id;


    # [
    Column(type: 'string', length: 100)]


    private int $name;


    }

    View Slide

  80. o Doctrine ORM 2.9 passou a suportar
    attributes e typed properties

    View Slide

  81. View Slide

  82. o Symfony 5.2 também passou a suportar
    attributes

    View Slide

  83. View Slide

  84. / /
    route def
    i
    nition in Symfony using attributes


    class SomeController


    {

    # [
    Route('/path', name: 'action')]


    public function someAction()


    {

    / / . . .

    }


    }

    View Slide

  85. Constructor

    Property Promotion

    View Slide

  86. durante a modelagem de objetos se faz
    necessário a utilização de muito boilerplate

    View Slide

  87. cada propriedade é repetida 4 vezes e
    seu tipo é repetido 2 vezes

    View Slide

  88. / /
    user implementation with excessive boilerplate


    class User


    {


    public int $id;


    public string $name;


    public string $email;


    public function
    _ _
    construct(


    int $id,


    string $name,


    string $email


    ) {


    $this
    - >
    id = $id;


    $this
    - >
    name = $name;


    $this
    - >
    email = $email;


    }


    }

    View Slide

  89. $user1 = new User(1, "Alice", "[email protected]");


    print_r($user1);


    / /
    User Object


    / /
    (


    / /
    [id]
    = >
    1


    / /
    [name]
    = >
    Alice


    / /
    [email]
    = >
    [email protected]


    / /
    )

    View Slide

  90. a partir do PHP 8.0 pode-se utilizar a funcio-
    nalidade constructor property promotion

    View Slide

  91. ela permite a redução do boilerplate para a
    criação de um objeto

    View Slide

  92. / /
    using constructor property promotion


    / /
    and with no boilerplate


    class User


    {


    public function
    _ _
    construct(


    public int $id,


    public string $name,


    public string $email


    ) {}


    }

    View Slide

  93. $user2 = new User(2, "Bob", "[email protected]");


    print_r($user2);


    / /
    User Object


    / /
    (


    / /
    [id]
    = >
    2


    / /
    [name]
    = >
    Bob


    / /
    [email]
    = >
    [email protected]


    / /
    )

    View Slide

  94. essa funcionalidade pode ser combinada
    com outras funcionalidades novas e reduzir
    a quantidade de código e torná-lo mais
    expressivo

    View Slide

  95. a constructor property promotion está
    disponível em diversas linguagens como
    Kotlin e TypeScript

    View Slide

  96. Union Types

    View Slide

  97. um union type permite fazer uma anotação
    de tipos com diferentes tipos

    View Slide

  98. o PHP já possui dois tipos especiais de union
    types: nullable types e iterable

    View Slide

  99. o tipo nullable possui a sintaxe ?Type e pode
    ser do tipo Type|null, isto é, Type ou null

    View Slide

  100. o tipo iterable pode ser do tipo array|
    Traversable, isto é, array ou Traversable

    View Slide

  101. declare(strict_types=1);


    / /
    using union type to annotate a function parameter


    function power(float|int $number, int $exponent)
    :
    int|float {


    return $number
    * *
    $exponent;


    }


    echo power(3, 2);
    / /
    9


    echo power(3.5, 2);
    / /
    12.25


    echo power('3', 2.5);


    / /
    Uncaught TypeError: power()
    :
    Argument #1 ($number) must be of


    / /
    type int|float, string given

    View Slide

  102. os union types são muito utilizado em
    projetos open-source e funções internas do
    PHP

    View Slide

  103. o suporte nativo permite a garantia de tipos
    pelo interpretador PHP e reduz a necessida-
    de de docblocks

    View Slide

  104. Throw Expression

    View Slide

  105. no PHP throw é uma instrução e não era
    possível lançar exceções em locais onde
    apenas expressões são permitidas…

    View Slide

  106. …como arrow functions, null coalesce
    operator e operador ternário

    View Slide

  107. / /
    trying to throw an exception in an expression shows a


    / /
    syntax error in PHP 7.4


    $function = fn()
    = >
    throw new Exception('an exception was thrown');


    $function();


    / /
    Parse error: syntax error, unexpected 'throw' (T_THROW)


    $nullableValue = null;


    $value = $nullableValue
    ? ?
    throw new Exception('null is not allowed');


    / /
    Parse error: syntax error, unexpected 'throw' (T_THROW)

    View Slide

  108. a partir do PHP 8.0 passou a ser possível
    utilizar throw como uma expressão

    View Slide

  109. essa funcionalidade é bastante útil e torna o
    código bastante expressivo

    View Slide

  110. / throwing an exception in an expression


    $function = fn()
    = >
    throw new Exception('an exception was thrown');


    $function();


    / /
    PHP 8.0 - Fatal error: Uncaught Exception: an exception was thrown


    $nullableValue = null;


    $value = $nullableValue
    ? ?
    throw new Exception('null is not allowed');


    / /
    PHP 8.0 - Fatal error: Uncaught Exception: null is not allowed

    View Slide

  111. Match Expressions

    View Slide

  112. costuma-se utilizar o switch para criar
    valores que serão usados no futuro

    View Slide

  113. porém, o switch tem os seguintes
    problemas:


    - esquecer a atribuição da variável em
    algum dos casos

    - possuir um boilerplate execessivo

    View Slide

  114. / /
    switch has an excessive boilerplate and is error prone


    switch ($statusCode) {


    case 200
    :

    $reasonPhrase = 'Ok';


    break;


    case 201
    :

    $reasonPhrase = 'Created';


    break;


    case 400
    :

    $reasonPhrase = 'Bad Request';


    break;


    }


    echo $result;
    / /
    Created

    View Slide

  115. o match não necessita da palavra-chave
    break após cada branch e possui um
    boilerplate mais enxuto

    View Slide

  116. / /
    match is less verbose and more expressive


    echo match ($statusCode) {


    200
    = >
    'Ok',


    201
    = >
    'Created',


    400
    = >
    'Bad Request',


    };
    / /
    Created

    View Slide

  117. o switch utiliza a comparação fraca (==) e
    pode levar a erros

    View Slide

  118. o match utiliza a comparação estrita (===) e
    leva a uma avaliação mais previsível
    independente do uso de strict_types

    View Slide

  119. utilização do break é uma das maiores
    fontes de erros ao utilizar o switch case

    View Slide

  120. o match resolve este problema por ter
    um break implícito em cada branch

    View Slide

  121. o match pode ter múltiplas condições para
    uma mesma branch

    View Slide

  122. / /
    match with multiple conditions for the same branch


    echo match($country) {


    'brazil', 'portugal'
    = >
    'portuguese',


    'argentina', 'spain', 'mexico'
    = >
    'spanish',


    default
    = >
    'another language'


    };
    / /
    portuguese

    View Slide

  123. a match expression deve contemplar todas
    as opções possíveis

    View Slide

  124. caso não exista uma branch correspondente
    ao resultado da expressão a exceção
    UnhandledMatchError será lançada

    View Slide

  125. PHP 8.1

    View Slide

  126. Enums

    View Slide

  127. uma enum de
    fi
    ne um novo tipo que
    possui número
    fi
    xo e limitado de valores
    possíveis

    View Slide

  128. / /
    creates an enum for the suits of a deck


    enum Suit {


    case Hearts;


    case Diamonds;


    case Clubs;


    case Spades;


    }


    $value = Suit
    : :
    Hearts;


    var_dump($value);
    / /
    enum(Suit
    : :
    Hearts)

    View Slide

  129. por padrão, os casos enumerados não
    possuem equivalentes escalares, isto é, eles
    são objetos singleton

    View Slide

  130. esse tipo de valor é chamado de pure case e
    uma enum que contém apenas pure cases é
    chamada de pure enum

    View Slide

  131. uma função ou método podem ser tipados
    com o tipo enum

    View Slide

  132. / /
    annotate a function parameter with an enum type


    function pick_a_card(Suit $suit) {}


    pick_a_card($value);
    / /
    ok


    pick_a_card(Suit
    : :
    Clubs);
    / /
    ok


    pick_a_card('Spades');


    / /
    Fatal error: Uncaught TypeError: pick_a_card()
    :

    Argument #1 ($suit) must be of type Suit, string given

    View Slide

  133. contudo, existem casos de usos em que é
    necessário ter equivalentes escalares para,
    por exemplo, persistir em uma base de
    dados

    View Slide

  134. / /
    create an enum backed with scalar values


    enum Suit: string {


    case Hearts = 'H';


    case Diamonds = 'D';


    case Clubs = 'C';


    case Spades = 'S';


    }


    var_dump(Suit
    : :
    Hearts);
    / /
    enum(Suit
    : :
    Hearts)


    var_dump(Suit
    : :
    Hearts
    - >
    name);
    / /
    string(6) "Hearts"


    var_dump(Suit
    : :
    Hearts
    - >
    value);
    / /
    string(1) "H"

    View Slide

  135. um case que possui um equivalente
    escalar é chamado de backed case pois
    é "suportado" por um valor mais simples

    View Slide

  136. uma enum que contém backed cases é
    chamado de backed enum

    View Slide

  137. um backed enum implementa a interface
    interna BackedEnum que expõe dois méto-
    dos adicionais que são from e tryFrom

    View Slide

  138. o método from() recebe um tipo escalar e
    retorna o case correspondente e, caso o
    valor não seja encontrado, a exceção
    ValueError é lançada

    View Slide

  139. o método tryFrom() possui comportamento
    similar mas, caso o valor não seja encontra-
    do, retorna nulo

    View Slide

  140. / /
    create an order status enum


    enum OrderStatus: string {


    case PendingPayment = 'pending_payment';


    case Processing = 'processing';


    case Completed = 'completed';


    case Refunded = 'refunded';


    case Cancelled = 'cancelled';


    }

    View Slide

  141. /
    /
    create an enum value using from() method with a valid value


    $orderStatus = OrderStatus
    :
    :
    from('processing');


    var_dump($orderStatus);
    /
    /
    enum(OrderStatus
    :
    :
    Processing)


    echo $orderStatus
    -
    >
    value;
    /
    /
    processing


    /
    /
    try to create an enum value using from() method with an invalid value


    $orderStatus = OrderStatus
    :
    :
    from('non_existent');


    /
    /
    Fatal error: Uncaught ValueError: "non_existent" is not a


    /
    /
    valid backing value for enum "OrderStatus"


    /
    /
    try to create an enum value using tryFrom() method with an invalid value


    $orderStatus = OrderStatus
    :
    :
    tryFrom('non_existent');


    var_dump($orderStatus);
    /
    /
    null

    View Slide

  142. Array Unpacking


    com chaves em string

    View Slide

  143. o PHP 7.4 tinha adicionado suporte para
    o unpacking de arrays em outros arrays
    utilizando o spread operator

    View Slide

  144. porém, não era permitido o unpacking de
    arrays com chaves em string devido: (1)
    incertezas em relação a semântica e (2)
    limitações no argument unpacking

    View Slide

  145. a limitação do argument unpacking foi
    resolvida graças a introdução de named
    arguments no PHP 8.0

    View Slide

  146. / /
    using array unpacking with string keys


    $user1 = ['name'
    = >
    'Alice'];


    $user2 = ['name'
    = >
    'Bob'];


    / /
    array unpacking with string keys in PHP 8.0 returns an error


    var_dump(array_merge($user1, $user2));
    / /
    ["name"
    = >
    "Bob"]


    var_dump([
    . . .
    $user1,
    . . .
    $user2]);


    / /
    Fatal error: Uncaught Error: Cannot unpack array with string keys


    / /
    array unpacking with string keys in PHP 8.1


    var_dump(array_merge($user1, $user2));
    / /
    ["name"
    = >
    "Bob"]


    var_dump([
    . . .
    $user1,
    . . .
    $user2]);
    / /
    ["name"
    = >
    "Bob"]

    View Slide

  147. com o suporte a essa funcionalidade é
    possível combinar as funcionalidades de
    argument unpacking e named arguments

    View Slide

  148. / /
    combine argument unpacking with named arguments


    function greet(string $greeting, string $name)
    :
    void {


    echo "$greeting, $name!" . PHP_EOL;


    }


    greet('Hi', 'Alice');
    / /
    Hi, Alice!


    greet('Bonjour', 'Bob');
    / /
    Bonjour, Bob!


    greet(greeting: 'Hallo', name: 'Carol');
    / /
    Hallo, Carol!


    greet(
    . . .
    ['name'
    = >
    'David', 'greeting'
    = >
    'Konichiwa']);
    / /
    Konichiwa David!

    View Slide

  149. Readonly Property

    View Slide

  150. uma propriedade readonly não pode ser
    modi
    fi
    cada após a sua inicialização

    View Slide

  151. os objetos de valores são imutáveis, isto é,
    as propriedades são inicializadas no
    construtor e não podem ser alteradas depois

    View Slide

  152. a alternativa mais próxima disso é declarar
    uma propriedade privada e expor um getter
    público

    View Slide

  153. / /
    create an email value object and exposes a getter method


    class Email {


    public function
    _ _
    construct(


    private string $value


    ) {

    / /
    throws an exception if the email is not valid


    $this
    - >
    value = $value;


    }


    public function value()
    :
    string {


    return $this
    - >
    value;


    }


    }

    View Slide

  154. o lado negativo dessa abordagem é
    necessitar de um boilerplate maior

    View Slide

  155. / /
    create an email value object with less boilerplate


    class Email {


    public function
    _ _
    construct(


    public readonly string $value


    ) {

    / /
    throws an exception if the email is not valid


    $this
    - >
    value = $value;


    }


    }


    $email = new Email('[email protected]');


    echo($email
    - >
    value);
    / /
    [email protected]


    $email
    - >
    value = '[email protected]';


    / /
    Uncaught Error: Cannot modify readonly property Email
    : :
    $value

    View Slide

  156. uma propriedade readonly só pode
    ser inicializada uma vez e somente no
    escopo em que ela foi declarada

    View Slide

  157. o modi
    fi
    cador readonly só pode ser aplicado
    em propriedades tipadas

    View Slide

  158. First-Class


    Callable Syntax

    View Slide

  159. trata-se de uma nova sintaxe para a criação
    de closures

    View Slide

  160. / /
    create closures with both old and new syntax


    $strlen1 = Closure
    : :
    fromCallable('strlen');


    $strlen2 = strlen(
    . . .
    );

    View Slide

  161. essa sintaxe é mais expressiva, acessível a
    ferramentas de análise estática e respeita o
    escopo em que foi criada

    View Slide

  162. Type Never

    View Slide

  163. o tipo never é um novo tipo de retorno
    adicionado no PHP 8.1

    View Slide

  164. uma função ou método declarados com
    o tipo de retorno never indica que nunca
    retornará um valor…

    View Slide

  165. …isto é, sempre lançará uma exceção ou
    terminará com die ou exit

    View Slide

  166. / creates a function with never return type


    function redirect(string $url)
    :
    never {


    echo "redirected to $url
    . . .
    \n";


    header('Location: ' . $url);


    exit();


    }


    redirect('https:
    / / w w w
    .example.com');


    / /
    redirected to https:
    / / w w w
    .example.com
    . . . 

    / /
    The rest of the code will not be executed!


    echo 'this will not be shown
    . . .
    ';

    View Slide

  167. o objetivo do tipo de retorno never é indicar
    uma função que previne que o resto do
    código chamado seja executado

    View Slide

  168. se uma função ou método com o tipo de
    retorno never não lançar uma exceção ou
    não terminar o programa será lançada
    a exceção TypeError

    View Slide

  169. / /
    create a function with never return type


    function dispatch(string $message)
    :
    never {


    echo $message;


    }


    dispatch('test');


    / /
    Uncaught TypeError: dispatch()
    :
    never
    -
    returning


    / /
    function must not implicitly return

    View Slide

  170. o suporte ao tipo de retorno never torna
    possível não utilizar mais a annotation
    @return noreturn

    View Slide

  171. Quando vou poder

    utilizá-lo?

    View Slide

  172. o PHP 8.1 estará disponível a partir do
    fi
    nal
    de novembro de 2021

    View Slide

  173. porém, as versões RC ou release candidates
    podem ser utilizadas agora para testes

    View Slide

  174. Ok! Como faço para

    utilizá-lo neste momento?

    View Slide

  175. a forma mais prática é a utilização de
    uma imagem Docker

    View Slide

  176. View Slide

  177. $ docker image pull php:8.1.0RC5-cli
    -
    alpine3.14

    View Slide

  178. $ alias php81='docker container run
    -
    it
    - -
    rm
    -
    v
    `pwd`:/app
    -
    w /app php:8.1.0RC5-cli
    -
    alpine3.14 php’

    View Slide

  179. $ php81
    - -
    version

    PHP 8.1.0RC5 (cli) (built: Oct 28 2021 23
    :
    22
    :
    17) (NTS)


    Copyright (c) The PHP Group


    Zend Engine v4.1.0-dev, Copyright (c) Zend Technologies

    View Slide

  180. dependendo do editor que você utilizar,
    você pode ter problemas com o syntax
    highlight e o aviso de erros do editor

    View Slide

  181. o PhpStorm 2021.2 já possui suporte para
    algumas funcionalidades do PHP 8.1

    View Slide

  182. Conclusão

    View Slide

  183. o PHP tem tido uma enorme evolução e tem
    se tornado uma linguagem mais robusta

    View Slide

  184. porém, sem perder a
    fl
    exibilidade e
    a pequena curva de aprendizado que o
    torna uma linguagem tão democrática

    View Slide

  185. as novas funcionalidades ajudarão o seu
    código a ter mais garantias, ser mais
    expressivo e te de dar mais poderes

    View Slide

  186. vá em frente e divirta-se!

    View Slide

  187. Avalie!

    View Slide

  188. @marcelgsantos
    speakerdeck.com/marcelgsantos
    Obrigado.
    Perguntas?

    View Slide