The 5th Annual China PHP Conference

Novos Recursos

Declarações de tipos escalares

Declaração de tipos escalares vem em dois sabores: coercivo (padrão) e restrito. Para parâmetros, os seguintes tipos podem ser forçados (tanto coercivamente quanto rigorosamente): strings (string), inteiros (int), números ponto-flutuante (float), e booleanos (bool). Eles incrementam os 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 rigoroso, uma simples diretiva declare deve ser colocada no topo do arquivo. Isso 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ção de tipo de retorno), funções internas do PHP e funções de extensões carregadas.

A documentação completa e exemplo de declarações de tipo escalar pode ser encontrada na referência de declaração de tipo.

Declarações de tipo de retorno

O PHP 7 adiciona o suporte a declarações de tipo de retorno. Similar as 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 para declarações para 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, assim como exemplos de declarações de tipo de retorno pode ser encontrada na referencia 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 uso de um ternário em conjunto com a função isset(). Retornará o primeiro operando se este existir e não for NULL; caso contrário retornará o segundo operando.

<?php
// Fetches the value of $_GET['user'] and returns 'nobody'
// if it does not exist.
$username $_GET['user'] ?? 'nobody';
// This is equivalent to:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

// Coalescing can be chained: this will return the first
// defined value out of $_GET['user'], $_POST['user'], and
// 'nobody'.
$username $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>

Operador "nave espacial" (spaceship)

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

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

// Floats
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 constantes utilizando a função define()

Array constantes agora podem ser definidos com a função define(). No PHP 5.6, só poderiam ser definidos com a função 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. Isso pode ser utilizado 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

Transforma códigos Unicode em sua forma hexadecimal e os imprime em uma string UTF-8 circundada por aspas ou um heredoc. Qualquer código válido é aceito, com o zero a esquerda sendo opcional.

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

O exemplo acima irá imprimir:

ª
ª (same as before but with optional leading 0's)
香

Closure::call()

O método Closure::call() é uma forma performática e mais fácil de vincular temporariamente um objeto a uma closure e invocá-la.

<?php
class {private $x 1;}

// Pre PHP 7 code
$getXCB = function() {return $this->x;};
$getX $getXCB->bindTo(new A'A'); // intermediate closure
echo $getX();

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

O exemplo acima irá imprimir:

1
1

unserialize() filtrado

Esse recurso busca prover a melhora na segurança na deserialização de objetos com informações não confiáveis. Prevê possíveis injeções de código habilitando o desenvolvedor a selecionar as classes que serão deserializadas.

<?php

// converts all objects into __PHP_Incomplete_Class object
$data unserialize($foo, ["allowed_classes" => false]);

// converts all objects into __PHP_Incomplete_Class object except those of MyClass and MyClass2
$data unserialize($foo, ["allowed_classes" => ["MyClass""MyClass2"]]);

// default behaviour (same as omitting the second argument) that accepts all 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 utilizadas 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 utilização desta classe, a extensão Intl deve ser instalada.

Expectations

Expectations são aprimoramentos retrocompatíveis com a antiga função assert(). Permitem asserções com custo zero em código em produção, e provêm a habilidade de lançar exceções personalizadas quando a asserção falha.

Como 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 que era avaliada ou um valor booleano a ser testado.

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

class 
CustomError extends AssertionError {}

assert(false, new CustomError('Some error message'));
?>

O exemplo acima irá imprimir:

Fatal error: Uncaught CustomError: Some error message

Mais detalhes sobre este recurso, incluindo como configurá-lo tanto no ambiente de desenvolvimento quanto em produção, pode ser encontrado na seção de expectations da referência do agora construtor, 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
// Pre PHP 7 code
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;

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

Retornar expressões em geradores

Este recurso foi construído em cima da funcionalidade de geradores introduzidas no PHP 5.5. Permite que a utilização da declaração return dentro de um gerador retorne uma expressão final (retornar por referência não é permitido). O valor pode ser recuperado usando o novo método Generator::getReturn(), que deve ser usando 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. Isso permite o retorno do valor final do gerador (pode ser de uma computação concorrente), poder ser manipulada especificamente por um código cliente executando no gerador. Isso é mais simples que forçar o código cliente a primeiro checar se o valor final já foi gerado, e em seguida, manipular o valor especificamente.

Delegação de geradores

Geradores agora podem ser delegados a outros geradores, objetos Traversable ou a um array automaticamente, sem a necessidade de escrever um gerador externo padrão 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 inteira com intdiv()

A nova função intdiv() faz a divisão inteira de seus operandos e as 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 comumente 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 pode ser passada para a função session_start() indicando que a informação da sessão deve ser lida e então imediatamente fechada sem ser modificada.

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 clara com a utilização da função preg_replace_callback(). Antes do PHP 7, callbacks que precisam ser executadas por expressões regulares requiridas pela função callback era poluída com diversas ramificações.

Agora, funções calback podem ser assimiladas a expressões regulares utilizando um array associativo, sendo que a chave é uma expressão regular, e o valor uma função callback.

Funções CSPRNG

Duas novas funções foram adicionadas na geração de inteiros e strings criptograficamente seguras de maneira interplataforma: random_bytes() e random_int().

a função list() consegue desempacotar objetos que implementam ArrayAccess

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

Outros Recursos

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

User Contributed Notes 3 notes

up
39
PawelD
10 months 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
-4
omarv_r at yahoo dot com
9 months 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
-19
lexx918 at mail dot ru
9 months 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