PHP 7.4 wychodzi w listopadzie 2019 i przynosi kilka zmian, które realnie wpłyną na codzienny kod. Typed properties to największa nowość – w końcu możemy deklarować typy bezpośrednio przy właściwościach klasy. Do tego arrow functions, operator nullsafe w preprodukcji i kilka pomniejszych usprawnień. Przeglądam zmiany na przykładach.
Typed Properties – nareszcie
Przed PHP 7.4 typy właściwości klas wymuszałeś przez konstruktor i docblock. Od 7.4 możesz deklarować typ bezpośrednio przy właściwości:
<?php
declare(strict_types=1);
class Product
{
// Przed PHP 7.4 - tylko docblock
/** @var int */
private $id;
/** @var string */
private $name;
// PHP 7.4 - typ bezpośrednio przy właściwości
private int $id;
private string $name;
private float $price;
private ?string $description = null; // nullable z wartością domyślną
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();
}
}
Właściwości bez wartości domyślnej są w stanie „uninitialized” do momentu przypisania. Próba odczytu takiej właściwości rzuca Error, a nie zwraca null – to ważna różnica od poprzednich wersji PHP:
<?php
class Broken
{
public int $count; // brak wartości domyślnej
}
$obj = new Broken();
echo $obj->count; // Error: Typed property Broken::$count must not be accessed before initialization
Arrow Functions – krótszy zapis anonimowych funkcji
Arrow functions (fn() =>) to skrócona składnia dla prostych funkcji anonimowych. Kluczowa różnica względem zwykłych closures: automatycznie przechwytują zmienne z otaczającego scope przez wartość – bez słowa kluczowego use:
<?php
$multiplier = 3;
// Przed PHP 7.4 - use wymagane do dostępu do $multiplier
$multiply = function(int $n) use ($multiplier): int {
return $n * $multiplier;
};
// PHP 7.4 - automatyczne przechwycenie przez wartość
$multiply = fn(int $n): int => $n * $multiplier;
echo $multiply(5); // 15
// Świetnie sprawdza się w array_map, array_filter, usort
$prices = [29.99, 9.99, 49.99, 14.99];
$discounted = array_map(fn(float $p): float => $p * 0.9, $prices);
$products = [
['name' => 'A', 'stock' => 0],
['name' => 'B', 'stock' => 5],
['name' => 'C', 'stock' => 3],
];
$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 w tablicach
PHP 7.4 rozszerza operator ... na literały tablic. Wcześniej działał tylko przy wywołaniach funkcji:
<?php $defaults = ['color' => 'red', 'size' => 'M', 'in_stock' => true]; $overrides = ['size' => 'XL', 'price' => 29.99]; // PHP 7.4 - spread w literale tablicy $product = [...$defaults, ...$overrides]; // ['color' => 'red', 'size' => 'XL', 'in_stock' => true, 'price' => 29.99] // Przydatne przy scalaniu konfiguracji w modułach $baseConfig = ['timeout' => 30, 'retries' => 3, 'debug' => false]; $moduleConfig = ['debug' => true, 'endpoint' => 'https://api.example.com']; $finalConfig = [...$baseConfig, ...$moduleConfig];
Operator ?? w przypisaniach (null coalescing assignment)
Skrót dla często powtarzającego się wzorca „przypisz jeśli null”:
<?php
// Przed PHP 7.4
$data['key'] = $data['key'] ?? 'default';
// PHP 7.4 - skrócony zapis
$data['key'] ??= 'default';
// Praktyczny przykład - inicjalizacja lazy cache
class ConfigCache
{
private array $cache = [];
public function get(string $key, callable $loader): mixed
{
$this->cache[$key] ??= $loader();
return $this->cache[$key];
}
}
Preloading – optymalizacja wydajności
PHP 7.4 dodaje mechanizm preloadingu – możesz wskazać skrypt PHP, który zostanie załadowany raz przy starcie PHP-FPM i pozostanie w pamięci dla wszystkich procesów. Dla Magento 2 to potencjalnie spora oszczędność czasu parsowania plików przy każdym requeście:
// php.ini opcache.preload=/var/www/magento/preload.php opcache.preload_user=www-data
<?php
// preload.php - przykład ładowania kluczowych klas
$files = glob('/var/www/magento/vendor/magento/framework/**/*.php');
foreach ($files as $file) {
opcache_compile_file($file);
}
W kontekście Magento 2 preloading wymaga ostrożności – platforma ma złożony autoloader i duże drzewo zależności. Warto eksperymentować ostrożnie i mierzyć wyniki.
Deprecacje w PHP 7.4
array_key_exists()na obiektach – użyjproperty_exists()- Zagnieżdżone wyrażenia ternarne bez nawiasów – PHP wymusi jawne nawiasowanie
- Dostęp do cudzysłowowych offsetów stringów przez
{}– zamiast$str{0}używaj$str[0]
<?php // Deprecated w PHP 7.4 - zagnieżdżony ternarny bez nawiasów // $result = $a ? $b : $c ? $d : $e; // błąd - niejednoznaczne // Poprawnie - z nawiasami $result = ($a ? $b : $c) ? $d : $e; // lub $result = $a ? $b : ($c ? $d : $e);
Podsumowanie
PHP 7.4 to solidna aktualizacja – typed properties porządkują kod klas, arrow functions skracają zapis w operacjach na kolekcjach, a preloading otwiera możliwości optymalizacji wydajności. Jeśli dbasz o czytelność kodu i statyczną analizę przez PHPStan, typed properties to zmiana, na którą warto zaktualizować istniejące klasy.
