WHat's new in PHP 8.0

MergePHP November 2020

Ian Littman / @iansltx

follow along at https://ian.im/php8merge

ETA: November 26, 2020 (two weeks!)

RC4 is out now

Thanks to release managers Sara Golemon and Gabriel Caruso

What we'll cover

  • Where to get it now
  • What's new
  • What's deprecated/removed
  • How to find out more information

How do I get it?

  • Useful for heavy computation
  • Less impactful when you're spending your time waiting for other services
  • CLI tools will run faster (e.g. exakat is ~15% faster)
  • Web workloads...probably not (but maybe with e.g. AMPHP?)
function query(
    PDO|PDOInterface $db, // same syntax as multi-catch
    string $query,
    ?array $params = []
): array|int {
    // do stuff
}
function query(
    PDO|PDOInterface $db,
    string|Stringable $query, // anything with __toString()
    ?array $params = []
): array|int {
    // do stuff
}
interface DoesAThing {
    function doAThing(mixed $thisCouldBeAnything): mixed;
# string|int|float|bool|null|array|object|callable|resource
}
query(query: 'SELECT 1', db: $pdo);

 

query(
    $pdo,
    params: ['one', 'two'],
    query: 'SELECT * FROM notes WHERE slug IN (?, ?)'
);

 

If you're writing a library, you have a whole new class of BC breaks to think about.

interface NoteRepo {
    public function findBySlug(string $slug): ?Note;
}
class Note   { public Author $author; }
class Author { public string $name; }

$notes->findBySlug('nonexistent')?->author->name; // ?string
switch (getRoute()) {
    case '/home':
    case '/':
        $title = 'Home Page';
        break;
    case '/profile':
        $title = getUserName();
        break;
    default:
        $title = 'My Great App!';
}
$title = match (getRoute()) {
    '/home', '/' => 'Home Page',
    '/profile' => getUserName(),
    default => 'My Great App!'
};
class DbColumn
{
    public function __construct(
        private string $name,
        private bool $nullable = false
    ) {
        echo $this->name . ' is '
            . ($nullable ? '' : 'not ')
            . "nullable\n";
    }
}
#[Attribute]
class DbColumn {
    public function __construct(
        private string $name,
        private bool $nullable = false
    ) {}
}

class Note {
    #[DbColumn('name')]
    public string $name;
}

$dbColumn = (new ReflectionClass('Note'))
    ->getProperties()[0] // $name property
    ->getAttributes()[0] // DbColumn ReflectionAttribute
    ->newInstance(); // DbColumn object with properties set
try {
    $api = API::connect();
    // do stuff with $api
} catch (BadApiKey) {
    // The type of the exception is enough to decide what
    // to do here, so we don't need the exception itself.
}

New functions | Methods!

String formatting additions

...and a few more

BC Break Time

echo strpos('needle', 'haystack', 1337);
// Now: Throws a ValueError
// THen: Returned false and emitted a warning
echo "Five plus three is " . 5 + 3;
// Now: "Five plus three is 8"
// Then: 3 (7.4 has a deprecation warning)

 

See https://3v4l.org/N2V4J

Resources -> Class Objects

trait Foo {
    abstract public function inParams(stdClass $item): array;
    abstract public function inReturn(stdClass $item): int;
}

class SuperFoo{
    use Foo;
    public function inParams(array $items): array{}
    //                       ^^^^^ Mismatch
    public function inReturn(stdClass $item): int{}
    //                                        ^^^ Mismatch
}

More fun with types

Throwing and logging

...and a few more

Further Reading

Thanks! Questions?

What's New in PHP 8.0 - MergePHP November 2020

By Ian Littman

What's New in PHP 8.0 - MergePHP November 2020

  • 1,290