#php80
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 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
#php80
#php80
- 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
- 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
- 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
#php80
`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
`match` Control Structure
`?->` Operator
Attributes
Union Types
Named Arguments
<?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;
}
}
<?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'
<?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
<?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;
}
}
<?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];
}
}
<?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];
}
}
<?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'
<?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
<?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
<?php declare(strict_types=1);
$value = 2;
echo match ($value) {
0 => 'Foo',
1 => 'Bar',
2 => 'Baz',
}; // Baz
<?php declare(strict_types=1);
$value = 3;
echo match ($value) {
0 => 'Foo',
1 => 'Bar',
2 => 'Baz',
}; // UnhandledMatchError: Unhandled match value of type int
<?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
}
<?php declare(strict_types=1);
$neighborhoodName = $address->getNeighborhood()?->getName();
if ($neighborhoodName !== null) {
// do something with $neighborhoodName
}
<?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]
<?php declare(strict_types=1);
var_dump(
array_fill(2, 3, 'PHP')
);
<?php declare(strict_types=1);
var_dump(
array_fill(2, 3, 'PHP')
); // [2 => 'PHP', 3 => 'PHP', 4 => 'PHP']
<?php declare(strict_types=1);
var_dump(
array_fill(start_key: 2, count: 3, value: 'PHP')
); // [2 => 'PHP', 3 => 'PHP', 4 => 'PHP']
<?php declare(strict_types=1);
class Person
{
public function __construct(string $name, int $age)
{
// ...
}
}
new Person(name: 'Gabriel Caruso', age: 22);
<?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?
<?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
<?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);
<?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
);
<?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
<?php declare(strict_types=1);
/** @Entity */
final class User
{
/**
* @ORM\Id()
* @ORM\Column(type="integer")
*/
private int $id;
/** @ORM\Column() */
private string $name;
}
Elas são usadas para documentar o seu código
Atributos mudam o comportamento do seu código. Pense em "meta programação"
<?php declare(strict_types=1);
#[Entity]
final class User
{
#[ORM\Id()]
#[ORM\Column(type="integer")]
private int $id;
#[ORM\Column()]
private string $name;
}
- 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
- 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
<?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
<?php declare(strict_types=1);
try {
$this->login($user);
} catch (PermissionException) { // $exception variable is no longer required
throw AuthenticationException::failedLogin();
}
<?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"
);
}
- 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
#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
- 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...
<?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
<?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"
<?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`
);
<?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*';
#php80
<?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*
#php80
<?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
#php80
#php80
- 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
#php80
Gabriel Caruso (sua primeira vez)
Sara Golemon (gerente do PHP 7.2)
#php80
- 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
Dmitry Stogov (JIT)
Nikita Popov (JetBrains)
#php80
Christoph M. Becker (Microsoft)
#php80
Matteo Beccati (PDO/Postgres)
#php80
#php80
#php80
Benjamin Eberlei (Doctrine)
#php80
Muito Obrigado ♥️
Por favor, deixe feedback para está palestra 👉🏻
Perguntas? 🤔