PHP 7

O que há de novidades?

Sumário

  1. Performance
  2. Novos recursos
  3. Recursos depreciados
  4. Funções modificadas
  5. Novas funções
  6. Extensões removidas
  7. Outras mudanças
  8. Incompatibilidades
  9. RFC: PHP 7.1
1

Perai...

e o que aconteceu com o PHP 6?

 

Performance

 
  • Engine remodelada (Zend Engine v3.0.0)

  • Aplicativos até 2x mais rápidos

  • Redução no consumo de memória

 

Benchmarks

 

PHP 5.6.18

 

PHP 7.0.3

 

Magento

 

Executa até 3x transações utilizando

o mesmo hardware

 

Drupal

 

Drupal 8 roda 72% mais rápido com PHP 7

 

Wordpress

 

Laravel/Zend Framework 2

 

SugarCRM

 

Comparação com outras linguagens

 

Novos recursos

 

Scalar type

<?php
// PHP 7: int, string, float and bool
// PHP 5: array, self, class/interface name and callable
function sum(int ...$values) {
    return array_sum($values);
}

var_dump(sum(1, 4, 3));
// int(8)

Return type

 
<?php
// PHP 7: bool, float, int, string, self, class/interface name, array and callable
function arraysSum(...$arrays): array {
    return array_map(function($array): int {
        return array_sum($array);
    }, $arrays);
}

var_dump(arraysSum([2, 4], [3, 6], [14, 2, 9]));
/*
array(3) {
  [0]=>
  int(6)
  [1]=>
  int(9)
  [2]=>
  int(25)
}
*/

Null coalescing operator

 
<?php
$name = 'Dorian';
var_dump($name ?? null);
// Dorian

// This is equivalent to:
var_dump(isset($name) ? $name : null);
// Dorian

unset($name);
$lastname = 'Neto';

// Coalescing can be chained:
var_dump($name ?? $lastname ?? null);
// Neto

Spaceship operator

 
<?php
echo 2 <=> 1; // 1
echo 2 <=> 2; // 0
echo 2 <=> 3; // -1

echo 1.2 <=> 1; // 1
echo 0.7 <=> 0.7; // 0
echo 0.5 <=> 1; // -1

Array em constantes utilizando define()

 
<?php
define('FULLNAME', [
    'Dorian',
    'Sampaio',
    'Neto'
]);

var_dump(FULLNAME);
/*
array(3) {
  [0]=>
  string(6) "Dorian"
  [1]=>
  string(7) "Sampaio"
  [2]=>
  string(4) "Neto"
}
*/

var_dump(FULLNAME[2]);
// Neto

Anonymous Classes

 
<?php
// RFC Anonymous Classes: https://wiki.php.net/rfc/anonymous_classes
interface Logger
{
    public function log(string $message);
}

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 $message)
    {
	return $message;
    }
});

var_dump($app->getLogger());
/*
object(class@anonymous)#2 (0) {
}
*/

var_dump($app->getLogger()->log('Log message'));
// string(11) "Log message"

Escape de caracteres UNICODE

 
<?php
echo "\u{00B5}"; // µ
echo "\u{00BD}"; // ½
echo "\u{00A9}"; // ©

Agrupamento de classes inclusas

 
<?php
// Pre PHP 7
use App\Controller\ClassA;
use App\Controller\ClassB;
use App\Controller\ClassC;

use function App\Controller\getA;
use function App\Controller\getB;
use function App\Controller\getC;

use const App\Controller\ConstA;
use const App\Controller\ConstB;
use const App\Controller\ConstC;

// PHP 7+
use App\Controller\{ClassA, ClassB as B, ClassC};
use function App\Controller\{getA, getB, getC};
use const App\Controller\{ConstA, ConstB, ConstC};

Divisão de números inteiros com intdiv()

 
<?php
var_dump(intdiv(10, 3));
// int(3)

Recursos depreciados

 

Declaração de construtor no estilo PHP 4

 
<?php
class Person
{
    function Person()
    {
	echo 'I am the Constructor';
    }
}
<?php
class Person
{
    public function __construct()
    {
	echo 'I am the Constructor';
    }
}

Chamada estática para métodos não estáticos

 
<?php
class Components
{
    public function paginate()
    {
	echo 'I am not a static method!';
    }
}

Components::paginate();
<?php
class Components
{
    public static function paginate()
    {
	echo 'I am not a static method!';
    }
}

Components::paginate();

Não é mais necessário a definição de salt na função password_hash()

 

Funções modificadas

 
  • dirname() - inserido um segundo parâmetro para navegação entre os diretórios pais

  • preg_replace() - função não da mais suporte ao modificador "\e"

  • exec(), system() e passthru() - agora possuem proteção contra NULL Byte Injection

  • substr() - se o parâmetro start for igual ao total de  caracteres do parâmetro string, o retorno é uma string vazia

 

Novas funções

 
  • random_int() - retorna número inteiro aleatório no intervalo inserido

  • random_bytes() - retorna string criptografada com número de bytes aleatórios passados como parâmetro

  • error_clear_last() - elimina o erro mais recente, impossibilitando recuperar através da função error_get_last() 

  • preg_replace_callback_array() - Executa busca e substituição em múltiplas expressões regulares

 

Extensões removidas

 
  • mysql

  • mssql

  • ereg

  • sybase_ct

 

Outras mudanças

 
  • Possiblidade de utilizar palavras reservadas globalmente (private, new, for etc)  em propriedades, constantes e métodos dentro de classes, interfaces e traits, com exceção de class para constantes (ClassName::class).

  • Remoção do aviso da não declaração do date.timezone nas configurações INI

 

Incompatibilidades

com versões anteriores ao PHP 7

 

Fatal Error agora é uma exceção!

 

Mudanças na manipulação de variáveis, propriedades e métodos indiretos

 
Expressão PHP5 PHP 7
$$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz']
$foo->$bar['baz'] $foo->{$bar['baz']} ($foo->$bar)['baz']
$foo->$bar['baz']() $foo->{$bar['baz']}() ($foo->$bar)['baz']()​
Foo::$bar['baz']() Foo::{$bar['baz']}() (Foo::$bar)['baz']()

Função list() não vai mais atribuir valores na ordem reversa 

 
<?php
list($v[], $v[], $v[]) = [1, 2, 3];
var_dump($v);
/*
array(3) {
  [0]=>
  int(3)
  [1]=>
  int(2)
  [2]=>
  int(1)
}
*/
<?php
list($v[], $v[], $v[]) = [1, 2, 3];
var_dump($v);
/*
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}
*/

PHP 5

PHP 7

Parênteses em torno de parâmetros de função não vai afetar o comportamento

 
<?php
function getArray() {
    return [5, 10, 15];
}

function changeArray(array &$array) {
    foreach ($array as &$value) {
        $value *= 2;
    }
}

// Generates a warning in PHP 7.
changeArray((getArray()));

// Output: Notice: Only variables should be passed by reference

Ponteiro interno do array não vai ser modificado no foreach

 
<?php
$array = [0, 1, 2];
foreach ($array as $value) {
    var_dump(current($array));
}
/*
int(1)
int(2)
bool(false)
*/
<?php
$array = [0, 1, 2];
foreach ($array as $value) {
    var_dump(current($array));
}
/*
int(0)
int(0)
int(0)
*/

PHP 5

PHP 7

foreach por referência verificará alterações no array durante a iteração

 
<?php
$array = [0];
foreach ($array as &$value) {
    var_dump($value);
    $array[1] = 1;
}
/*
int(0)
*/
<?php
$array = [0];
foreach ($array as &$value) {
    var_dump($value);
    $array[1] = 1;
}
/*
int(0)
int(1)
*/

PHP 5

PHP 7

Mudanças em divisões por zero

 
<?php
var_dump(2/0);
// Warning: Division by zero in %s on line %d
// bool(false)

var_dump(0/0);
// Warning: Division by zero in %s on line %d
// bool(false)

var_dump(0%0);
// Warning: Division by zero in %s on line %d
// bool(false)


<?php
var_dump(2/0);
// Warning: Division by zero in %s on line %d
// float(INF)

var_dump(0/0);
// Warning: Division by zero in %s on line %d
// float(NAN)

var_dump(0%0);
// PHP Fatal error:  Uncaught DivisionByZeroError: Modulo by zero in %s line %d

PHP 5

PHP 7

strings hexadecimais não são mais consideradas numéricas

 
<?php
var_dump("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" + "0x1");
var_dump(substr("foo", "0x1"));

// bool(true)
// bool(true)
// int(15)
// string(2) "oo"
<?php
var_dump("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" + "0x1");
var_dump(substr("foo", "0x1"));

// bool(false)
// bool(false)
// int(0)

// Notice: A non well formed numeric value encountered in /tmp/test.php on line 5
// string(3) "foo"

PHP 5

PHP 7

Funções não podem ter múltiplos parâmetros com o mesmo nome

 
<?php
function paginate($slug, array $slug = []) {
    // code...
}
<?php
function paginate($slug, array $arr_slug = []) {
    // code...
}

switch não pode ter múltiplas declarações default

 
<?php
switch($value) {
    default:
    break;
    default:
    break;
}
<?php
switch($value) {
    default:
    break;
}

A variável global $HTTP_RAW_POST_DATA foi removida

ASP tags e Script PHP tags foram removidas!

 
<%

// code...

%>
<h1><%=$value%></h1>
<script language="php">

// code...

</script>

RFC

PHP 7.1

 

Short list syntax

<?php
// Creates an array
$array = [1, 2, 3];
 
// Extracts its elements into variables
[$a, $b, $c] = $array;
  • Descrição: Utilização de colchete para atribuir valores de uma matriz para variáveis
     
  • Status: Implementado
  • Votos: 41 (sim) x 0 (não)

Nullable types

<?php
function answer(): ?int  {
    return null;
}
var_dump(answer()); // ok
 
function answer(): ?int  {
    return 42;
}
var_dump(answer()); // ok

function say(?string $msg) {
    if ($msg) {
        echo $msg;
    }
}
 
say('hello'); // ok -- prints hello
say(null); // ok -- does not print
say(); // error -- missing parameter
  • Descrição: Utilização de ponto de interrogação para indicar que o valor retornado ou esperado pode ser null
     
  • Status: Aceito
  • Votos: 41 (sim) x 2 (não)

Void return type

<?php
function returns_nothing(): void {
    return;
}
var_dump(returns_nothing()); // valid

function returns_one(): void {
    return 1; 
}
var_dump(returns_one()); // Fatal error
  • Descrição: Inclusão de novo tipo void para funções de retorno vazio
     
  • Status: Implementado
  • Votos: 37 (sim) x 7 (não)

Class Constant Visibility

<?php
 
class Token {
    // Constants default to public
    const PUBLIC_CONST = 0;
 
    /*
    Constants then also can have a
    defined visibility
    */ 
    private const PRIVATE_CONST = 0;
    protected const PROTECTED_CONST = 0;
    public const PUBLIC_CONST_TWO = 0;
}
  • Descrição: Inclusão de suporte para controle de visibilidade (public, protected e private) de constantes em classes
     
  • Status: Implementado
  • Votos: 28 (sim) x 2 (não)

Catching Multiple

<?php
 
try {
   // Some code...
} catch (ExceptionType1 $e) {
   // Code to handle the exception
} catch (ExceptionType2 $e) {
   // Same code to handle the exception
} catch (Exception $e) {
   // ...
}
  • Descrição: Possibilidade de tratar mais de uma exceção no mesmo bloco try/catch
     
  • Status: Implementado
  • Votos: 40 (sim) x 6 (não)

Obrigado!

 
@doriansneto dorianneto.com.br dorianneto (Github)

PHP 7 - O que há de novidades?

By Dorian Neto

PHP 7 - O que há de novidades?

Slides desenvolvidos para a palestra de PHP7 - O que há de novidades? apresentado no 1º Encontro de desenvolvedores de Fortaleza/CE promovido pela comunidade PHP com Rapadura.

  • 3,043