PHP 7.4 arrives in November 2019 and brings several changes that will have a real impact on everyday code. Typed properties are the headline feature – at last we can declare types directly on class properties. Plus arrow functions, spread in arrays, and the null coalescing assignment operator.
Typed Properties – finally
Before PHP 7.4 you enforced property types through the constructor and docblocks. From 7.4 you declare the type directly on the property:
<?php
declare(strict_types=1);
class Product
{
// PHP 7.4 - type directly on the property
private int $id;
private string $name;
private float $price;
private ?string $description = null; // nullable with default
private \DateTimeImmutable $createdAt;
public function __construct(int $id, string $name, float $price)
{
$this->id = $id;
$this->name = $name;
$this->price = $price;
$this->createdAt = new \DateTimeImmutable();
}
}
Properties without a default value are in an “uninitialized” state until assigned. Reading such a property throws an Error, not null:
<?php
class Broken
{
public int $count; // no default value
}
$obj = new Broken();
echo $obj->count; // Error: Typed property must not be accessed before initialization
Arrow Functions – shorter anonymous function syntax
Arrow functions (fn() =>) automatically capture variables from the surrounding scope by value – no use keyword needed:
<?php
$multiplier = 3;
// Before PHP 7.4 - use required
$multiply = function(int $n) use ($multiplier): int {
return $n * $multiplier;
};
// PHP 7.4 - automatic capture by value
$multiply = fn(int $n): int => $n * $multiplier;
echo $multiply(5); // 15
// Works great with array operations
$prices = [29.99, 9.99, 49.99, 14.99];
$discounted = array_map(fn(float $p): float => $p * 0.9, $prices);
$taxRate = 0.23;
$inStock = array_filter($products, fn(array $p): bool => $p['stock'] > 0);
$withTax = array_map(
fn(array $p): array => array_merge($p, ['tax' => $p['stock'] * $taxRate]),
$inStock
);
Spread operator in arrays
<?php $defaults = ['color' => 'red', 'size' => 'M', 'in_stock' => true]; $overrides = ['size' => 'XL', 'price' => 29.99]; // PHP 7.4 - spread in array literal $product = [...$defaults, ...$overrides]; // ['color' => 'red', 'size' => 'XL', 'in_stock' => true, 'price' => 29.99] // Useful when merging module config $baseConfig = ['timeout' => 30, 'retries' => 3, 'debug' => false]; $moduleConfig = ['debug' => true, 'endpoint' => 'https://api.example.com']; $finalConfig = [...$baseConfig, ...$moduleConfig];
Null coalescing assignment operator
<?php
// Before PHP 7.4
$data['key'] = $data['key'] ?? 'default';
// PHP 7.4 - shorthand
$data['key'] ??= 'default';
// Practical: lazy cache initialisation
class ConfigCache
{
private array $cache = [];
public function get(string $key, callable $loader): mixed
{
$this->cache[$key] ??= $loader();
return $this->cache[$key];
}
}
Deprecations in PHP 7.4
array_key_exists()on objects – useproperty_exists()- Nested ternary expressions without brackets – PHP now requires explicit parenthesising
- Curly brace string offset access: use
$str[0]instead of$str{0}
Summary
PHP 7.4 is a solid update – typed properties clean up class code, arrow functions shorten collection operation expressions, preloading opens performance optimisation possibilities. If you care about code readability and static analysis, typed properties is a change worth backporting to existing classes.
