PHP 7.2

PHP Usergroup Münster

@benjamincremer

Read the Migration Guide

New features
New functions
New global constants
Backward incompatible changes
Deprecated features in PHP 7.2.x
Other changes

php.net/manual/en/migration72.php

Deprecations

Deprecations

  • __autoload() method
  • create_function()
  • (unset) cast
  • each() function
  • mbstring.func_overload ini setting
  • $errcontext argument of error handlers
  • and more

php.net/manual/en/migration72.deprecated.php

Bareword (Unquoted) Strings


$foo = NONEXISTENT;

// PHP 7.2
// Warning: Use of undefined constant fasle - assumed 'NONEXISTENT'
// (this will throw an Error in a future version of PHP)

// Older Versions
// Notice: Use of undefined constant fasle - assumed 'NONEXISTENT'

Mcrypt no longer in core

Can be installed via pecl. DONT DO IT! (alternative ahead)

Counting of non-countable objects


var_dump(
    count(1), // integers are not countable
    count('abc'), // strings are not countable
    count(new stdclass) // objects not implementing Countable
);

// Warning: count(): Parameter must be an array or
// an object that implements Countable

New Features

Object data type


function foo(object $definitelyAnObject): object
{
    return 'another string';
}

foo('what about some string?');
// TypeError: Argument 1 passed to foo() must be an object, string given, called in...


foo(new \stdClass());
// TypeError: Return value of foo() must be an object, string returned

Debugging information for PDO

PDOStatement::debugDumpParams()
.. now returns the SQL sent to the database, including the full, raw query including the replaced placeholders with their bounded values.
Only in emulated mode

Parameter Type Widening


class LibraryClass
{
    public function doWork(string $input)
    {

    }
}

class UserClass extends LibraryClass
{
    public function doWork($input)
    {

    }
}

// PHP <7.2.0
// Warning: Declaration of UserClass::doWork($input) should be
// compatible with LibraryClass::doWork(string $input) in …

                    

Trailing commas in list syntax


// Arrays (already possible)
$array = [1, 2, 3,];

// Grouped namepaces
use Foo\Bar\{ Foo, Bar, Baz, };

// Function/method arguments (call)
fooCall($arg1, $arg2, $arg3,);

class Foo implements
    FooInterface,
    BarInterface,
    BazInterface,
{


Argon2 in password hash



$options = [
    // number of KiB that should be consumed
    // (default values are 1<<10, or 1024 KiB, or 1 MiB)
    'memory_cost' => PASSWORD_ARGON2_DEFAULT_MEMORY_COST,
    // number of iterations of the hashing algorithm
    // (defaults to 2)
    'time_cost' => PASSWORD_ARGON2_DEFAULT_TIME_COST,
    // number of parallel threads that will be used
    // (defaults to 2)
    'threads' => PASSWORD_ARGON2_DEFAULT_THREADS,
];
password_hash('password', PASSWORD_ARGON2I, $options);
https://wiki.php.net/rfc/argon2_password_hash

Password Hashing


$hash = password_hash($password, PASSWORD_DEFAULT);

if (password_verify($password, $hash)) {
    // Authenticated.
    if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
        // Rehash, update database.
    }
}
How to Safely Store Your Users' Passwords in 2016

Libsodium

Libsodium as part of PHP Core

Sodium is a chemical element with symbol Na

libsodium is a Fork of NaCl

Modern crypto for 2017

Poorly documented at php.net

Argon2i Key Derivation


$password = 'My password';

// create a random salt
$salt = random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES);
$outLen = SODIUM_CRYPTO_SIGN_SEEDBYTES;

$seed = sodium_crypto_pwhash(
    $outLen,
    $password,
    $salt,
    SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
    SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
var_dump(strlen($seed)); // 32

Authenticated secret key encryption


function encrypt(string $plaintext, string $password): string
{
    $salt = random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES);
    $key = deriveKeyFromUserPassword($password, $salt);

    $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
    $ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $key);

    return $salt.$nonce.$ciphertext;
}

Authenticated secret key encryption


function decrypt(string $ciphertext, string $password): string
{
    // split string into parts
    $salt = substr($ciphertext, 0, SODIUM_CRYPTO_PWHASH_SALTBYTES);
    $nonce = substr($ciphertext, SODIUM_CRYPTO_PWHASH_SALTBYTES, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
    $ciphertext = substr($ciphertext, SODIUM_CRYPTO_PWHASH_SALTBYTES + SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

    $key = deriveKeyFromUserPassword($password, $salt);

    $plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
    if ($plaintext === false) {
        throw new \InvalidArgumentException('Bad ciphertext');
    }

    return $plaintext;
}
Code on Github

New Functions

Example: stream_isatty()

New Global Constatns

Example: PHP_OS_FAMILY
Either of 'Windows', 'BSD', 'Darwin', 'Solaris', 'Linux' or 'Unknown'

PHP 7.2 Polyfill

spl_object_id(), stream_isatty(), utf8_encode(), utf8_decode(), sapi_windows_vt100_support(), PHP_OS_FAMILY

PHP 7.2 Polyfill component

The future is now

Run PHP 7.2 Today


# Ubuntu / Debian
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install php7.2-cli

# Mac OSX
brew tap homebrew/homebrew-php
brew install php72

# Docker
docker run -it --rm php:7.2