php[tek] 2018 : Call for Speakers

Novos Recursos

Declarações de tipos escalares

Declarações de tipos escalares vêm em dois sabores: coercivo (padrão) e estrito. Para parâmetros os seguintes tipos agora podem ser forçados (tanto coercivamente quanto estritamente): strings (string), inteiros (int), números de ponto flutuante (float) e booleanos (bool). Eles incrementam os outros tipos introduzidos no PHP 5: nomes de classe, interfaces, array e callable.

<?php
// Modo coercivo
function sumOfInts(int ...$ints)
{
    return 
array_sum($ints);
}

var_dump(sumOfInts(2'3'4.1));

O exemplo acima irá imprimir:

int(9)

Para habilitar o modo estrito, uma única diretiva declare deve ser colocada no topo do arquivo. Isto significa que a rigorosidade de tipificação para escalares é configurada por arquivo. Esta diretiva não afeta somente as declarações de tipo de parâmetros, mas também do tipo de retorno de funções (veja declarações de tipo de retorno), funções internas do PHP e funções de extensões carregadas.

A documentação completa e exemplos de declarações de tipo escalar podem ser encontradas na referência de declaração de tipo .

Declarações de tipo de retorno

O PHP 7 adiciona suporte a declarações de tipo de retorno. Similar às declarações de tipo de argumento as declarações de tipo de retorno especificam o tipo do valor que será retornado por uma função. Os mesmos tipos estão disponíveis para declarações de tipo de retorno assim como estão disponíveis para declarações de tipo de argumentos.

<?php

function arraysSum(array ...$arrays): array
{
    return 
array_map(function(array $array): int {
        return 
array_sum($array);
    }, 
$arrays);
}

print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));

O exemplo acima irá imprimir:

Array
(
    [0] => 6
    [1] => 15
    [2] => 24
)

A documentação completa e exemplos de declarações de tipo de retorno podem ser encontradas na referência de declarações de tipo de retorno .

Operador de coalescência nula

O operador de coalescência nula (??) foi adicionado como um truque sintático para o caso trivial de precisar usar um ternário em conjunto com a função isset(). Ele retorna o primeiro operando se este existir e não for NULL; caso contrário retorna o segundo operando.

<?php
// Obtém o valor de $_GET['user'] e retorna 'nobody'
// se ele não existir.
$username $_GET['user'] ?? 'nobody';
// Isto equivale a:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

// A coalescência pode ser encadeada: isto irá retornar o primeiro
// valor definido entre $_GET['user'], $_POST['user'] e
// 'nobody'.
$username $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>

Operador "nave espacial" (spaceship)

O operador nave espacial é utilizado para comparar duas expressões. Ele retorna -1, 0 ou 1 quando $a for respectivamente menor que, igual a ou maior que $b. As comparações são feitas de acordo com as já conhecidas regras de comparação de tipos do PHP.

<?php
// Inteiros
echo <=> 1// 0
echo <=> 2// -1
echo <=> 1// 1

// Números de ponto flutuante
echo 1.5 <=> 1.5// 0
echo 1.5 <=> 2.5// -1
echo 2.5 <=> 1.5// 1

// Strings
echo "a" <=> "a"// 0
echo "a" <=> "b"// -1
echo "b" <=> "a"// 1
?>

Arrays de constantes utilizando a função define()

Constantes do tipo array agora podem ser definidas com a função define(). No PHP 5.6 elas só poderiam ser definidas com const.

<?php
define
('ANIMALS', [
    
'dog',
    
'cat',
    
'bird'
]);

echo 
ANIMALS[1]; // imprime "cat"
?>

Classes anônimas

O suporte a classes anônimas foi adicionado utilizando new class. Estas podem ser utilizadas no lugar de definições completas de classes para objetos descartáveis.

<?php
interface Logger {
    public function 
log(string $msg);
}

class 
Application {
    private 
$logger;

    public function 
getLogger(): Logger {
         return 
$this->logger;
    }

    public function 
setLogger(Logger $logger) {
         
$this->logger $logger;
    }
}

$app = new Application;
$app->setLogger(new class implements Logger {
    public function 
log(string $msg) {
        echo 
$msg;
    }
});

var_dump($app->getLogger());
?>

O exemplo acima irá imprimir:

object(class@anonymous)#2 (0) {
}

A documentação completa pode ser encontrada na referência de classes anônimas.

Sintaxe de escape de códigos Unicode

Toma um código Unicode em sua forma hexadecimal e imprime esse código em UTF-8 em uma string delimitada por aspas ou um heredoc. Qualquer código válido é aceito, com os zeros à esquerda sendo opcionais.

echo "\u{aa}";
echo "\u{0000aa}";
echo "\u{9999}";

O exemplo acima irá imprimir:

ª
ª (o mesmo que antes mas com os zeros à esquerda opcionais)
香

Closure::call()

O método Closure::call() é uma forma mais eficaz e abreviada de associar temporariamente um escopo de objeto a uma closure e invocá-la.

<?php
class {private $x 1;}

// Código anterior ao PHP 7
$getXCB = function() {return $this->x;};
$getX $getXCB->bindTo(new A'A'); // intermediate closure
echo $getX();

// Código do PHP 7+
$getX = function() {return $this->x;};
echo 
$getX->call(new A);

O exemplo acima irá imprimir:

1
1

unserialize() filtrado

Esse recurso busca prover uma melhor segurança ao desserializar objetos com informações não confiáveis. Ele impede possíveis injeções de código ao permitir que o desenvolvedor liste as classes que podem ser desserializadas.

<?php

// converte todos os objetos em objetos __PHP_Incomplete_Class
$data unserialize($foo, ["allowed_classes" => false]);

// converte todos os objetos em objetos __PHP_Incomplete_Class exceto aqueles de MyClass e MyClass2
$data unserialize($foo, ["allowed_classes" => ["MyClass""MyClass2"]]);

// comportamento padrão (o mesmo que omitir o segundo argumento) que aceita todas as classes
$data unserialize($foo, ["allowed_classes" => true]);

IntlChar

A nova classe IntlChar busca expor funcionalidades adicionais da ICU. A classe define alguns métodos estáticos e constantes que podem ser utilizados para manipular caracteres unicode.

<?php

printf
('%x'IntlChar::CODEPOINT_MAX);
echo 
IntlChar::charName('@');
var_dump(IntlChar::ispunct('!'));

O exemplo acima irá imprimir:

10ffff
COMMERCIAL AT
bool(true)

Para utilizar esta classe a extensão Intl deve estar instalada.

Expectations

Expectations são aprimoramentos compatíveis com versões anteriores para a antiga função assert(). Permitem asserções com custo zero em código em produção e fornecem a capacidade de lançar exceções personalizadas quando a asserção falha.

Enquanto a API antiga continua sendo mantida por motivos de compatibilidade, assert() agora é um construtor de linguagem, permitindo que o primeiro parâmetro seja uma expressão, em vez de somente uma string a ser avaliada ou um valor booleano a ser testado.

<?php
ini_set
('assert.exception'1);

class 
CustomError extends AssertionError {}

assert(false, new CustomError('Alguma mensagem de erro'));
?>

O exemplo acima irá imprimir:

Fatal error: Uncaught CustomError: Alguma mensagem de erro

Mais detalhes sobre este recurso, incluindo como configurá-lo tanto no ambiente de desenvolvimento quanto em produção, podem ser encontrados na seção de expectations da referência do construtor de linguagem assert();

Agrupamento de declarações use

Classes, funções e constantes importadas do mesmo namespace, agora podem ser agrupadas em uma única declaração use

<?php
// Código anterior ao PHP 7
use some\namespace\ClassA;
use 
some\namespace\ClassB;
use 
some\namespace\ClassC as C;

use function 
some\namespace\fn_a;
use function 
some\namespace\fn_b;
use function 
some\namespace\fn_c;

use const 
some\namespace\ConstA;
use const 
some\namespace\ConstB;
use const 
some\namespace\ConstC;

// Código do PHP 7+
use some\namespace\{ClassAClassBClassC as C};
use function 
some\namespace\{fn_afn_bfn_c};
use const 
some\namespace\{ConstAConstBConstC};
?>

Expressões de Retorno nos Geradores

Este recurso foi construído em cima da funcionalidade de geradores introduzida no PHP 5.5. Ele permite que uma declaração return seja usada dentro de um gerador para permitir que uma expressão final seja retornada (retornar por referência não é permitido). Este valor pode ser obtido usando o novo método Generator::getReturn(), que deve ser usado somente quando o gerador terminar a geração dos valores.

<?php

$gen 
= (function() {
    
yield 1;
    
yield 2;

    return 
3;
})();

foreach (
$gen as $val) {
    echo 
$valPHP_EOL;
}

echo 
$gen->getReturn(), PHP_EOL;

O exemplo acima irá imprimir:

1
2
3

A habilidade de retornar explicitamente o valor final de um gerador é conveniente de se ter. Ela permite que o retorno do valor final do gerador (pode ser de uma computação concorrente) possa ser manipulado especificamente pelo código cliente que executa o gerador. Isso é bem mais simples que forçar o código cliente a primeiro checar se o valor final já foi gerado, e em caso afirmativo, manipular esse valor especificamente.

Delegação de geradores

Geradores agora podem delegar para outros geradores, objetos Traversable ou array automaticamente, sem a necessidade de escrever código repetitivo no gerador externo utilizando o construtor yield from

<?php
function gen()
{
    
yield 1;
    
yield 2;
    
yield from gen2();
}

function 
gen2()
{
    
yield 3;
    
yield 4;
}

foreach (
gen() as $val)
{
    echo 
$valPHP_EOL;
}
?>

O exemplo acima irá imprimir:

1
2
3
4

Divisão de inteiros com intdiv()

A nova função intdiv() realiza a divisão de inteiros de seus operandos e a retorna.

<?php
var_dump
(intdiv(103));
?>

O exemplo acima irá imprimir:

int(3)

Opções de sessões

A função session_start() agora aceita um array de opções que sobrescrevem as diretivas de configuração de sessões normalmente configuradas no php.ini.

Estas opções também foram expandidas para suportar session.lazy_write, que está habilitada por padrão e faz com que o PHP somente sobrescreva um arquivo de sessão se a informação da sessão foi modificada, e read_and_close, que é uma opção que só pode ser passada para a função session_start() para indicar que os dados da sessão devem ser lidos e, em seguida, a sessão deve ser imediatamente fechada sem alterações.

Por exemplo, para configurar session.cache_limiter para private e fechar imediatamente a sessão após lê-la:

<?php
session_start
([
    
'cache_limiter' => 'private',
    
'read_and_close' => true,
]);
?>

preg_replace_callback_array()

A nova função preg_replace_callback_array() permite que o código seja escrito de forma mais limpa com a utilização da função preg_replace_callback(). Antes do PHP 7, callbacks que precisam ser executadas por expressões regulares exigiam que a função de callback fosse poluída com muitas ramificações.

Agora, funções de callback podem ser registradas em cada expressão regular utilizando um array associativo, onde a chave é uma expressão regular e o valor é uma função de callback.

Funções CSPRNG

Duas novas funções foram adicionadas para gerar inteiros e strings criptograficamente seguros de maneira multiplataforma: random_bytes() e random_int().

A função list() pode sempre desempacotar objetos que implementam ArrayAccess

Antes a função list() não garantia corretude em operações com objetos que implementam ArrayAccess. Isso foi corrigido.

Outros Recursos

  • Acesso a membros de classe na clonagem foi adicionado, por exemplo, (clone $foo)->bar().
add a note add a note

User Contributed Notes 5 notes

up
73
PawelD
1 year ago
<?php
class foo { static $bar = 'baz'; }
var_dump('foo'::$bar);
?>

if < php7.0

then we will receive a syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)

but php7 returns string(3) "baz"

I think it's not documented anywhere
up
3
TerryE
5 months ago
$a = ''; // or 0 or false

$b = $a ?? 'a'; 
// $b is '' or 0 or false

$c = $a ?: 'a';
// $c is 'a'
up
-13
omarv_r at yahoo dot com
1 year ago
lexx918, It is not working unexpectedly... lets see:

Calling to isset() method for a non existing property ($foo->bar in this case), automatically the magic method __isset() is invoked. So

$a = isset($foo->bar) ?: null; // __isset

is correct.

But when we try to evaluate $foo->bar, we are calling a getter. Because the bar property does not exist, the implicit calling is to magic method __get(). So

$a = $foo->bar ?? null; // __get

is correct too.
up
-13
robert.j.pounder
4 months ago
<?php
class foo { static $bar = 'baz'; }
var_dump('foo'::$bar);

and
variations dont work

but

<?php
class foo { static $bar = 'baz'; }
$t = 'foo';
var_dump($t::$bar);

works < 7.0
up
-70
lexx918 at mail dot ru
1 year ago
Sugar of ternary operator:
<?php
$a
?? 'b'
// allegedly equivalent to
isset($a) ? $a : 'b'
?>
.. in classes working unexpectedly:
<?php
class Foo {
    public function
__get($p) { echo "__get" . PHP_EOL; }
    public function
__isset($p) { echo "__isset" . PHP_EOL; }
}
$foo = new Foo;
$a = isset($foo->bar) ?: null; // __isset
$a = $foo->bar ?? null; // __get
?>
To Top