What’s new in PHP 8 !

#New features

#Union types rfc

public function foo(Foo|Bar $input): int|float;
public function foo(Foo|null $foo): void;public function bar(?Bar $bar): void;

#JIT rfc

#Attributes rfc

use App\Attributes\ExampleAttribute;<<ExampleAttribute>>
class Foo
{
<<ExampleAttribute>>
public const FOO = 'foo';

<<ExampleAttribute>>
public $x;

<<ExampleAttribute>>
public function foo(<<ExampleAttribute>> $bar) { }
}
<<PhpAttribute>>
class ExampleAttribute
{
public $value;

public function __construct($value)
{
$this->value = $value;
}
}

#Constructor property promotion rfc

class Money 
{
public Currency $currency;

public int $amount;

public function __construct(
Currency $currency,
int $amount,
) {
$this->currency = $currency;
$this->amount = $amount;
}
}
class Money 
{
public function __construct(
public Currency $currency,
public int $amount,
) {}
}

#New static return type rfc

class Foo
{
public function test(): static
{
return new static();
}
}

#New mixed type rfc

  • A function returns nothing or null
  • We’re expecting one of several types
  • We’re expecting a type that can’t be type hinted in PHP
  • array
  • bool
  • callable
  • int
  • float
  • null
  • object
  • resource
  • string
// Fatal error: Mixed types cannot be nullable, null is already part of the mixed type.
function bar(): ?mixed {}

#Throw expression rfc

$triggerError = fn () => throw new MyError();$foo = $bar['offset'] ?? throw new OffsetDoesNotExist('offset');

#Weak maps rfc

class Foo 
{
private WeakMap $cache;

public function getSomethingWithCaching(object $obj): object
{
return $this->cache[$obj]
??= $this->computeSomethingExpensive($obj);
}
}

#Allowing ::class on objects rfc

$foo = new Foo();var_dump($foo::class);

#Non-capturing catches rfc

try {
// Something goes wrong
} catch (MySpecialException $exception) {
Log::error("Something went wrong");
}
try {
// Something goes wrong
} catch (MySpecialException) {
Log::error("Something went wrong");
}

#Trailing comma in parameter lists rfc

public function(
string $parameterA,
int $parameterB,
Foo $objectfoo,
) {
// …
}

#Create DateTime objects from interface

DateTime::createFromInterface(DateTimeInterface $other);DateTimeImmutable::createFromInterface(DateTimeInterface $other);

#New Stringable interface rfc

class Foo
{
public function __toString(): string
{
return 'foo';
}
}
function bar(Stringable $stringable) { /* … */ }bar(new Foo());
bar('abc');

#New str_contains() function rfc

if (strpos('string with lots of words', 'words') !== false) { /* … */ }
if (str_contains('string with lots of words', 'words')) { /* … */ }

#New str_starts_with() and str_ends_with() functions rfc

str_starts_with('haystack', 'hay'); // true
str_ends_with('haystack', 'stack'); // true

#New fdiv() function pr

#New get_debug_type() function rfc

#New get_resource_id() function pr

$resourceId = (int) $resource;
$resourceId = get_resource_id($resource);

#Abstract methods in traits improvements rfc

trait Test {
abstract public function test(int $input): int;
}
class UsesTrait
{
use Test;
public function test($input)
{
return $input;
}
}
class UsesTrait
{
use Test;
public function test(int $input): int
{
return $input;
}
}

#Object implementation of token_get_all() rfc

#Variable syntax tweaks rfc

#Type annotations for internal functions externals

#ext-json always available rfc

#Breaking changes

#Consistent type errors rfc

#Reclassified engine warnings rfc

  • Undefined variable: Error exception instead of notice
  • Undefined array index: warning instead of notice
  • Division by zero: DivisionByZeroError exception instead of warning
  • Attempt to increment/decrement property ‘%s’ of non-object: Error exception instead of warning
  • Attempt to modify property ‘%s’ of non-object: Error exception instead of warning
  • Attempt to assign property ‘%s’ of non-object: Error exception instead of warning
  • Creating default object from empty value: Error exception instead of warning
  • Trying to get property ‘%s’ of non-object: warning instead of notice
  • Undefined property: %s::$%s: warning instead of notice
  • Cannot add element to the array as the next element is already occupied: Error exception instead of warning
  • Cannot unset offset in a non-array variable: Error exception instead of warning
  • Cannot use a scalar value as an array: Error exception instead of warning
  • Only arrays and Traversables can be unpacked: TypeError exception instead of warning
  • Invalid argument supplied for foreach(): TypeError exception instead of warning
  • Illegal offset type: TypeError exception instead of warning
  • Illegal offset type in isset or empty: TypeError exception instead of warning
  • Illegal offset type in unset: TypeError exception instead of warning
  • Array to string conversion: warning instead of notice
  • Resource ID#%d used as offset, casting to integer (%d): warning instead of notice
  • String offset cast occurred: warning instead of notice
  • Uninitialized string offset: %d: warning instead of notice
  • Cannot assign an empty string to a string offset: Error exception instead of warning
  • Supplied resource is not a valid stream resource: TypeError exception instead of warning

#The @ operator no longer silences fatal errors

#Default error reporting level

#Default PDO error mode rfc

#Concatenation precedence rfc

echo "sum: " . $a + $b;
echo ("sum: " . $a) + $b;
echo "sum: " . ($a + $b);

#Stricter type checks for arithmetic and bitwise operators rfc

[] % [42];
$object + 4;

#Reflection method signature changes

ReflectionClass::newInstance($args);
ReflectionFunction::invoke($args);
ReflectionMethod::invoke($object, $args);
ReflectionClass::newInstance(...$args);
ReflectionFunction::invoke(...$args);
ReflectionMethod::invoke($object, ...$args);
ReflectionClass::newInstance($arg = null, ...$args);
ReflectionFunction::invoke($arg = null, ...$args);
ReflectionMethod::invoke($object, $arg = null, ...$args);

#Fatal error for incompatible method signatures rfc

#Other deprecations and changes

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store