Applicazioni web professionali in PHP 7

Dott. Enrico Zimuel
Senior Software Engineer
Rogue Wave Software, Inc.


Università Torino, Dipartimento Informatica, 4 Dic. 2018

Enrico Zimuel

www.sviluppareinphp7.it

PHP

  • PHP: Hypertext Preprocessor
  • Il linguaggio server-side più utilizzato al mondo: circa il 78% di tutti i siti web (fonte: w3techs.com)
  • Alcuni utenti del PHP: Facebook, Wikipedia, Yahoo, Etsy, Flickr, Digg, etc
  • 23 anni di utilizzo, dal 1995
  • Ad oggetti (OOP) dal PHP 5

L'ecosistema PHP

PHP 7

Ultima release stabile 7.2.12 (8 Nov 2018)

Performance PHP 7


$a = [];
for ($i = 0; $i < 1000000; $i++) {
  $a[$i] = ["hello"];
}
echo memory_get_usage(true);
PHP 5.6 PHP 7.2
Memoria 428 MB 34 MB
Tempo di esecuzione 0.59 sec 0.06 sec

Altri linguaggi

PHP 7 è anche più veloce di Python 3!

Casi di studio

  • Badoo risparmia un milione di dollari l'anno grazie a PHP 7 (fonte)
  • Tumblr riduzione del 50% della latenza e del carico della CPU, grazie a PHP 7 (fonte)
  • Dailymotion gestisce il doppio del traffico web con la stessa infrastruttura, grazie a PHP 7 (fonte)
Versione Rilascio Supporto Security fix
5.6 28 Ago 2014 19 Gen 2017 31 Dic 2018
7.0 3 Dic 2015 3 Dic 2017 3 Dic 2018
7.1 1 Dic 2016 1 Dic 2018 1 Dic 2019
7.2 30 Nov 2017 30 Nov 2019 30 Nov 2020

PHP 6 ?

Supporto Unicode a livello del linguaggio

Mai rilasciato, progetto abbandonato

Applicazioni professionali

  • Framework di sviluppo
  • Versionamento dei sorgenti
  • Gestione delle dipendenze
  • Testing del codice
  • Sicurezza
  • Log e monitoring
  • File di configurazione
  • Deploy in produzione

Framework di sviluppo

Laravel, Symfony, Zend Framework

Expressive, Lumen, Slim, Silex

Versionamento

Git

github.com, bitbucket.org

Gestione dipendenze

Composer

composer.json:


{
    "require": {
        "monolog/monolog": "1.0.*"
    }
}

Test

PHPUnit


use PHPUnit\Framework\TestCase;

class EmailTest extends TestCase
{
    public function testCanBeUsedAsString()
    {
        $this->assertEquals(
            'user@example.com',
            Email::fromString('user@example.com')
        );
    }
}

Sicurezza

Filter Input, Escape Output

password_hash(), password_verify()

OpenSSL: openssl_encrypt/decrypt, Sodium

Log e monitoring

error_log()

monolog

File di configurazione

Yaml, Json, Xml, Ini, oppure PHP


// config.php
return [
    'db' => [
        'dsn' => 'mysql:dbname=test;host=127.0.0.1',
        'user' => 'test',
        'password' => 'dH34f23q8Bvdrt34'
    ]
];

// index.php
$config = require 'config.php'; // $config['db']['dsn']

Deploy in produzione

Deployer, Ansible

Vagrant, Docker

Novità 7.1

Tipo Nullable

  • Per parametri e valori di ritorno di funzioni
  • Sintassi: aggiunta del ? prima del tipo
  • null può essere passato come argomento,
    o restituito come valore

Example


function hi(?string $name): ?string
{
    return $name ? 'Hello ' . $name : null;
}

echo hi(null); // returns null
echo hi('Enrico'); // returns 'Hello Enrico'
echo hi(); // Fatal error

Ritorno di tipo Void


function swap(&$a, &$b): void
{
    if ($a === $b) {
        return;
    }
    $tmp = $a;
    $a   = $b;
    $b   = $tmp;
}
$a = 1;
$b = 2;
var_dump(swap($a, $b), $a, $b);

Iterable

  • Aggiunto lo pseudo-tipo iterable
  • Accetta array o Traversable
  • Utilizzato in parametri e ritorno di funzioni

Esempio


function foo(iterable $iterable): void
{
    foreach ($iterable as $value) {
        var_dump($value);
    }
}

foo([1,2,3]);
foo(new ArrayIterator([1,2,3]));

Costanti di classe


class ConstDemo
{
    const CONST_A = 1; // public
    public const CONST_B    = 2;
    protected const CONST_C = 3;
    private const CONST_D   = 4;
}

Catch multipli


try {
   // Some code...
} catch (ExceptionA | ExceptionB $e) {
   // Handle exceptions A or B
} catch (\Exception $e) {
   // ...
}

Indici negativi


var_dump("abcdef"[-2]); // string(1) "e"
var_dump("abcdef"[-7]); // string(0) "", PHP Notice
// strpos
var_dump(strpos("aabbcc", "b", -3)); // int(3)

// get the last character of a string
$last = substr($foo, -1); // before PHP 7.1
$last = $foo[-1];

OpenSSL AEAD

Cifratura e autenticazione (Authenticated Encryption)

Supporto modalità GCM e CCM

GCM è 3 volte più veloce di CCM. Dettagli benchmark

Più informazioni su Authenticated Encryption in PHP 7.1

Mcrypt

Estensione deprecata

Utilizzare OpenSSL al suo posto

Novità 7.2

Performance

PHP 7.2 è 20% più veloce di 7.0 e 10% di 7.1
Fonte: benchmark di Michael Larabel

Tipo Object

Utilizzabile come parametro e ritorno di tipo


function foo(object $obj): string {
    return $obj->var;
}

function bar(MyClass $arg): object {
    return $arg;
}

Type overriding

Omissione del tipo su classi astratte estese:


abstract class A
{
    abstract function test(string $s);
}

abstract class B extends A
{
    abstract function test($s) : int;
}

Si mantiente la covarianza e controvarianza dei tipi

SQL sent

Aggiunta informazione di debug su PDO: la query SQL generata da PDOStatement


$pdo = new PDO(
    'mysql:dbname=test;host=localhost',
    'user',
    'password'
);
$sth = $pdo->prepare(
    "SELECT * FROM user WHERE active=:active"
);
$sth->execute(['active' => true]);
$sth->debugDumpParams();

SQL sent (2)


SQL: [39] SELECT * FROM user WHERE active = :active
Sent SQL: [35] SELECT * FROM user WHERE active='1'
Params:  1
Key: Name: [7] :active
paramno=-1
name=[7] ":active"
is_param=1
param_type=2

Argon2

Supporto algoritmo Argon2i per l'hash delle password


$password = 'test';
$hash = password_hash($password, PASSWORD_ARGON2I);
var_dump($hash);

$hash conterrà una stringa di 98 caratteri

Sodium

Supporto crittografia moderna con la nuova estesione Sodium basata sulla libreria libsodium

Maggiori informazioni: Modern cryptography in PHP 7.2

PHP 7.3

  • Rilascio: 6 Dic 2018
  • Virgola finale nelle chiamate di funzione
    
    foo($bar, $baz,);
    
  • JSON_THROW_ON_ERROR
    
    try {
      json_decode("{", false, 512, JSON_THROW_ON_ERROR);
    } catch (\JsonException $exception) {
      echo $exception->getMessage(); // Syntax error
    }
    

PHP 7.3 (2)

  • Aggiunta funzione is_countable()
    
    if (is_array($foo) || $foo instanceof Countable) {
        // $foo is countable
    }
    if (is_countable($foo)) {
        // $foo is countable
    }
    
  • Nuove funzioni array_key_first(), array_key_last()
  • Supporto PASSWORD_ARGON2ID
  • Altre novità

PHP 7.4 - Typed Properties


class Example {
    // Tutti i tipi sono supportati (a parte void e callable)
    public int $scalarType;
    protected ClassName $classType;

    // Anche su proprietà statiche
    public static iterable $staticProp;

    // E' possibile utilizzare la notazione var
    var bool $flag;

    // Valori predefiniti
    public string $str = "foo";
    public ?string $nullableStr = null;

    // Unica dichiarazione per più variabili
    public float $x, $y;
}

Maggiori info: RFC typed_properties_v2

PHP 7.4 - Preloading

  • Condivisione in memoria di script PHP
  • Riduce i tempi di lettura/verifica dei file opcode
  • Ispirato alla funzionalità di Class Data Sharing di Java HotSpot VM
  • la direttiva opcache.preload del php.ini specifica il file da precaricare
  • la funzione opcache_compile_file($file), carica un file in memoria condivisa

Maggiori info: RFC preloading

Grazie!

Contatti: enrico [at] zimuel.it

Web: www.zimuel.it

Twitter: @ezimuel



Creative Commons License
Questa presentazione è rilasciata con licenza
Creative Commons Attribution-ShareAlike 3.0 Unported License.
Presentazione realizzata con reveal.js