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?
- macOS (nightly builds)
- brew tap shivammathur/php
- brew install shivammathur/php/php@8.0
- Ubuntu/Debian instructions (aka use Ondrej's repo)
- Red Hat-based: use Remi's repo
- Inside Docker: e.g. php:8.0.0RC4-fpm-alpine3.12
- Windows builds can be downloaded here
- Source code to build yourself is on php.net
- 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!
- fdiv() - float division with INF/-INF returned for division by 0
- get_debug_type() - more accurate gettype() (names match typehints)
- str_contains(), str_starts_with(), str_ends_with() - returns booleans (vs. strpos)
- preg_last_error_msg() - friendlier message on why your regex match failed
- get_resource_id() - (int) $resource with type safety
- DateTime|DateTimeImmutable::createFromInterface()
String formatting additions
- %h, %H in printf format for locale-independent floats
- Precision/width modifiers in printf
-
"p" TZ offset param for DateTime::format() to show UTC as "Z" vs. "+0000"
So now you can use Y-m-d\TH:i:sp (existing constnts are unaffected)
...and a few more
- Auto-select port for PHP built-in web server
- Tweak trace-as-string argument max length
- JSON extension is now built in
- You can now throw exceptions anywhere an expression is expected
- If you disable a function, it now behaves as if it doesn't exist
- $object::class now works
- Private functions can be overridden by subclasses...except for final constructors
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)
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
- ian.im/php8merge - these slides
- twitter.com/iansltx - me, online
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,256