Olá!

Eu souDiego!

O layout desses slides foi clonado do Ocramius também conhecido como Marco Pivetta
(o cara do Doctrine/ZendFramework)

Você pode acessar o original aqui github.com/Ocramius/zf2-best-practices

Ele esteve aqui em João Pessoa em outubro/2015 participando do PHPESTE

Migrando do PHP 5.6
para o PHP 7.0

Sobre o que é essa apresentação?

Não é sobre
Mágica

Não falarei sobre scripts de migração automática

Mais overview do que
aprofundamento no código

Calma que já vamos começar!

O que diz a documentação?

O PHP 7 está em desenvolvimento!

(algumas coisas ainda podem mudar)

Você SABE
por onde começar?

Existe incompatibilidade com versões anteriores?

Alguma função nova ou alterada?

Em relação a classes, interfaces e constantes há algo de novo?

Que tal começar com a performance?

Os slides a seguir foram criados por Rasmus Lerdorf (criador do PHP)

Estão disponíveis no link talks.php.net/oz15

Test Box Specs

  • Gigabyte Z87X-UD3H i7-4771 4 cores @ 3.50GHz w/ 16G of Ram @ 1600MHz
  • Hyperthreading enabled for a total of 8 virtual cores
  • Toshiba THNSNHH256GBST SSD
  • Linux debian 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u1 x86_64 GNU/Linux
  • MySQL 5.6.22
  • nginx-1.2.1 + php-fpm for all tests unless indicated otherwise
  • Quiet local 100Mbps network
  • siege benchmark tool run from a separate machine

Dados disponíveis em talks.php.net/oz15

Dados disponíveis em talks.php.net/oz15

Dados disponíveis em talks.php.net/oz15

Dados disponíveis em talks.php.net/oz15

Dados disponíveis em talks.php.net/oz15

Dados disponíveis em talks.php.net/oz15

Dados disponíveis em talks.php.net/oz15

Compatibilidade com versões anteriores

Mudanças na captura de erros e exceções

Muitos erros fatais foram convertidos em exceções

Essas exceções herdam da classe Error

A classe Error implementa a interface Throwable

Mudanças severas no E_STRICT

Faltando assinatura ao usar herança E_WARNING
Acessando propriedade estática "não-estaticamente" E_NOTICE
Chamando métodos não estáticos estaticamente | $foo::bar(); E_DEPRECATED

Variáveis, propriedades e métodos

Expression PHP 5 interpretation PHP 7 interpretation
$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']()

Mudanças na manipulação do list()

Não atribui mais os valores na ordem inversa


list($a[], $a[], $a[]) = [1, 2, 3];
var_dump($a);
                    

O código anterior no

PHP 5


array(3) {
  [0]=>
  int(3)
  [1]=>
  int(2)
  [2]=>
  int(1)
}
                    

O mesmo código no

PHP 7


array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}
                    

Sobre o list()

Não deixe seu código apegado à ordenação

Foi removida a opção de list() vazio

Não desempacota mais - use o str_split() para isso

Ordenação de Arrays

quando os elementos são criados durante passagem por referência

Mudança na ordenação dos elementos


$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
                     

O código anterior no

PHP 5


array(2) {
    ["b"]=>
    &int(1)
    ["a"]=>
    &int(1)
}
                    

O mesmo código no

PHP 7


array(2) {
    ["a"]=>
    &int(1)
    ["b"]=>
    &int(1)
}
                    

global aceita apenas variáveis simples

Variáveis variáveis não podem ser usadas com a palavra-chave global


function f() {
    // Valid in PHP 5 only.
    global $$foo->bar;

    // Valid in PHP 5 and 7.
    global ${$foo->bar};
}
                    

Procure não usar uma variável global "do nada"

O uso de parênteses nos parâmetros de funções não tem mais efeito

No PHP 5, o uso de parênteses no parâmetro da função quando o parêmetro é uma outra função, não exibia warning

function getArray() {
    return [1, 2, 3];
}
function squareArray(array &$a) {
    foreach ($a as &$v) {
        $v **= 2;
    }
}
// Generates a warning in PHP 7.
squareArray((getArray()));

Notice: Only variables should be passed by reference in /tmp/test.php on line 13

Mudanças no foreach

foreach por valor opera numa cópia do array

Isso significa que as mudanças feitas no array durante a iteração, não irão afetar os valores iterados

Melhora no comportamento da iteração no foreach "por referência"

Quando você iterar sobre um array "por referência", o PHP 7 irá manter a iteração atualizada sobre mudanças no array


$array = [0];
foreach ($array as &$val) {
    var_dump($val);
    $array[1] = 1;
}
                    

No PHP 7 você irá incrementar o array que está sendo iterado

O código abaixo no PHP 5


$array = [0];
foreach ($array as &$val) {
    var_dump($val);
    $array[1] = 1;
}
                    

Irá imprimir:


int(0)
                    

O código abaixo no PHP 7


$array = [0];
foreach ($array as &$val) {
    var_dump($val);
    $array[1] = 1;
}
                    

Irá imprimir:


int(0)
int(1)
                    

Nomes inválidos para Classes, Interfaces e Traits


bool
int
float
string
NULL
TRUE
FALSE
                    

Reservados para o futuro

Nomes que não irão causar erro mas estão reservados para o futuro e devem ser considerados deprecated


resource
object
mixed
numeric
                    

Tags ASP e script PHP foram removidas

Tag de abertura Tag de fechamento
<% %>
<%= %>


                    

Comentários em arquivos INI com # foram removidos

O suporte a comentários com # foi removido e agora deve ser utilizado o ; (ponto e vírgula)

As mudanças se aplicam tanto ao arquivo php.ini quanto aos manipulados por parse_ini_file() e parse_ini_string()

Novos recursos

Declaração de tipo escalar

A declaração de tipos agora vai além de nomes de classes, interfaces e arrays

A declaração de tipos no PHP 7 agora inclui:

Strings (string)

Integers (int)

Floating-point numbers (float)

Booleans (bool)

Ver documentação

Exemplo de declaração de tipo


// Coercive mode
function sumOfInts(int ...$ints)
{
    return array_sum($ints);
}

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

O exemplo acima imprime:


int(9)
                    

Declaração de tipo de retorno

O PHP 7 adicionou o suporte a declaração de tipo de retorno

Similar à declaração de tipo de argumento, especifica o tipo de retorno que uma função irá retornar

Exemplo de declaração de tipo de retorno


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]));
                    

Operador coalesce para NULL

O operador coalesce para NULL (??) foi adicionado como um incremento sintático para as situações onde se usa o ternário junto ao isset()

Exemplo de uso do operador coalesce ??:


// 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';

// Coalesces 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 spaceship

O operador spaceship (isso mesmo, operador "nave espacial"), é usado para comparar dois valores

Ele irá retorna -1, 0 ou 1 quando o valor $a for respectivamente menor que, igual a ou maior que $b

As comparações são realizadas seguindo a mesma regra de comparação de tipos já existente

Exemplo de uso do operador spaceship <=>


// Integers
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 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
                    

Constantes de array usando define()

Constantes de Array agora podem ser definidas com o define(). No PHP 5.6 só podiam com o const (fora da definição de uma classe)

Exemplo de definição de constantes de Array


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

echo ANIMALS[1]; // outputs "cat"
                    

Classes anônimas

Suporte a classes anônimas foi adicionado através do new class

Exemplo de definição de classe anônima


// Leve em consideração que já foram criadas
// a interface Logger e a classe Application...

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

Documentação de classes anônimas

Declaração agrupada do use

Classes, funções e constantes importadas do mesmo namespace agora podem ser agrupadas no mesmo statement use

Exemplo de uso agrupado do use


// 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\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};
                    

Nova função intdiv() para divisão de inteiros

Executa uma divisão de inteiros e retorna um inteiro

Exemplos de uso do intdiv()


var_dump(intdiv(3, 2));
var_dump(intdiv(-3, 2));
var_dump(intdiv(3, -2));
var_dump(intdiv(-3, -2));
var_dump(intdiv(PHP_INT_MAX, PHP_INT_MAX));
var_dump(intdiv(PHP_INT_MIN, PHP_INT_MIN));
var_dump(intdiv(PHP_INT_MIN, -1));
var_dump(intdiv(1, 0));
                    

Retorna:


int(1)
int(-1)
int(-1)
int(1)
int(1)
int(1)

Fatal error: Uncaught ArithmeticError: Division of PHP_INT_MIN by -1 is not an integer in %s on line 8
Fatal error: Uncaught DivisionByZeroError: Division by zero in %s on line 9
                    

Opções para o session

session_start() agora aceita um array de opções que sobrescreve o que estiver definido no php.ini

Exemplo de uso do session_start()

Se você quiser por exemplo alterar o parâmetro session.cache_limiter para private e fechar a sessão imediatamente após a leitura pode usar:


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

Duas novas funções foram criadas para retornar inteiros e strings criptograficamente seguros

random_bytes()

random_int()

Exemplo de uso do ramdon_bytes()


$bytes = random_bytes(5);
var_dump(bin2hex($bytes));
                    

Retorna algo similar a:


string(10) "385e33f741"
                    

Exemplo de uso do ramdon_int()


var_dump(random_int(100, 999));
var_dump(random_int(-1000, 0));
                    

Retorna algo similar a:


int(248)
int(-898)
                    

Recursos deprecated no PHP 7.0.x

Construtores no estilo PHP 4

Construtores no estilo do PHP 4 (onde o construtor tem o mesmo nome da função) agora são deprecated e serão removidos no futuro

O PHP 7 irá emitir um E_DEPRECATED se o um construtor PHP 4 for o único construtor da classe

Classes que implementam __construct() não serão afetadas

Exemplo de uso de construtor PHP 4 (deprecated)


class foo {
    function foo() {
        echo 'I am the constructor';
    }
}
                    

O exemplo acima irá imprimir:


Deprecated: Methods with the same name as their class
will not be constructors in a future version of PHP;
foo has a deprecated constructor in example.php on line 3
                    

Chamadas estáticas a métodos não estáticos


class foo {
    function bar() {
        echo 'I am not static!';
    }
}

foo::bar();
                    

O exemplo acima irá imprimir:


Deprecated: Non-static method foo::bar()
should not be called statically in - on line 8
I am not static!
                    

Que tal montar seu próprio ambiente de testes no PHP 7?

Instale o Vagrant e Virtualbox

Em seguida:


$ git clone https://github.com/rlerdorf/php7dev.git

$ cd php7dev

$ vagrant up
... (takes a bit - it is downloading 1.5G)

$ vagrant ssh
                    

Sua máquina estará disponível no IP fixo 192.168.7.7

Ao acessar http://192.168.7.7

Será exibida a página phpinfo() do PHP 7

Mudar entre as versões é muito fácil


vagrant@php7dev:~$ sudo newphp 56
Activating PHP 5.6.6-dev and restarting php-fpm

vagrant@php7dev:~$ sudo newphp 7 debug
Activating PHP 7.0.0-dev and restarting php-fpm
                    

Estão disponíveis 20 versões pre-compiladas começando na 5.3

Referências

github.com/tpunt/PHP7-Reference

github.com/rlerdorf/php7dev

talks.php.net/oz15#/

Muito obrigado!

Fique à vontade para me seguir no GitHub

github.com/diegonobre