· Admin

PHP 8.4 ve 8.5 Yenilikleri: Laravel Geliştiricileri İçin Rehber

PHP 8.4 Kasim 2024'te yayinlandi ve 8.5 de 2025 sonunda bizi bekliyor. Her iki surum de Laravel gelistiricileri icin gunden gune daha fazla anlam ifade eden ozellikler iceriyor. Bu makalede her iki surumun one cikan ozelliklerini, Laravel projelerimde nasil kullandigimi ve gunluk kodumu nasil degistirdigini paylasiyorum.

PHP 8.4 Yenilikleri

Property Hooks

PHP 8.4'un en buyuk yeniligi tartismasiz property hook'lari. Artik getter ve setter metotlari yerine dogrudan property uzerinde hook tanimlayabiliyoruz.

class Product
{
    public string $name {
        set(string $value) => $this->name = trim($value);
    }

    public float $price {
        set(float $value) {
            if ($value < 0) {
                throw new InvalidArgumentException('Fiyat negatif olamaz.');
            }
            $this->price = $value;
        }
        get => round($this->price, 2);
    }

    public string $slug {
        get => Str::slug($this->name);
    }
}

Laravel'de bu ozelligi ozellikle DTO (Data Transfer Object) ve Value Object'lerde kullaniyorum:

class MoneyValue
{
    public function __construct(
        private float $amount,
        private string $currency = 'TRY',
    ) {}

    public float $formatted {
        get => round($this->amount, 2);
    }

    public string $display {
        get => number_format($this->amount, 2, ',', '.') . ' ' . $this->currency;
    }
}

$price = new MoneyValue(149.9);
echo $price->display; // "149,90 TRY"

Asymmetric Visibility

Property'lere farkli erisim seviyeleri tanimlamak artik mumkun. Disaridan okunabilir ama sadece sinif icinden yazilabilir:

class User
{
    public private(set) string $email;
    public protected(set) int $loginCount = 0;

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

    public function recordLogin(): void
    {
        $this->loginCount++;
    }
}

$user = new User('[email protected]');
echo $user->email;       // OK - public read
$user->email = 'test';   // HATA - private set

Bu ozellik Eloquent model'lerde henuz dogal olarak kullanilamiyor cunku Eloquent kendi attribute sistemini kullaniyor. Ama servis siniflarinda, DTO'larda ve config objelerinde muhtesem calisiyor.

Yeni Array Fonksiyonlari

PHP 8.4 ile gelen array_find, array_find_key, array_any ve array_all fonksiyonlari Collection kullanmadigim yerlerde hayat kurtariyor:

$users = [
    ['name' => 'Ali', 'role' => 'admin'],
    ['name' => 'Veli', 'role' => 'editor'],
    ['name' => 'Ayse', 'role' => 'admin'],
];

// Ilk admin'i bul
$admin = array_find($users, fn($u) => $u['role'] === 'admin');
// ['name' => 'Ali', 'role' => 'admin']

// Herhangi bir admin var mi?
$hasAdmin = array_any($users, fn($u) => $u['role'] === 'admin');
// true

// Hepsi admin mi?
$allAdmin = array_all($users, fn($u) => $u['role'] === 'admin');
// false

Laravel Collection zaten bu islemleri yapiyordu ama raw array'lerle calisirken (config dosyalari, API response parse etme gibi) bu fonksiyonlar cok isime yariyor.

Lazy Objects

PHP 8.4 ile reflection API'ye lazy object destegi geldi. Obje ilk erisilinceye kadar initialize edilmiyor:

$reflector = new ReflectionClass(HeavyService::class);

$service = $reflector->newLazyProxy(function () {
    // Bu closure sadece $service ilk kullanildiginda calisir
    return new HeavyService(
        config: loadExpensiveConfig(),
        connection: createDbConnection(),
    );
});

// Henuz HeavyService olusturulmadi
// ...
$service->process(); // Simdi olusturuluyor ve calistirilior

Laravel'in service container'i zaten lazy resolution yapiyor ama kendi siniflarinizda bu pattern'i kullanmak istediginizde artik native destek var.

DOM HTML5 Destegi

Eski DOMDocument sinifi HTML5'i duzgun parse edemiyordu. PHP 8.4 ile gelen Dom\HTMLDocument sinifi bu sorunu cozuyor:

$doc = Dom\HTMLDocument::createFromString('<main><article>Icerik</article></main>');
$articles = $doc->querySelectorAll('article');

foreach ($articles as $article) {
    echo $article->textContent; // "Icerik"
}

Web scraping veya email template islemlerinde bu sinif cok daha guvenilir sonuclar veriyor.

PHP 8.5 Yenilikleri (Beklenen)

PHP 8.5 henuz gelistirme asamasinda ama onaylanan ve tartisilan ozellikler var. Bunlarin en onemli birkacindan bahsedeyim.

Pipe Operator (|>)

Fonksiyonel programlamadan ilham alan pipe operator, nested fonksiyon cagrilarini okunakli hale getiriyor:

// Onceki yol - icten disa okumak zor
$result = array_sum(array_map(fn($x) => $x * 2, array_filter($numbers, fn($x) => $x > 0)));

// PHP 8.5 pipe operator ile
$result = $numbers
    |> fn($arr) => array_filter($arr, fn($x) => $x > 0)
    |> fn($arr) => array_map(fn($x) => $x * 2, $arr)
    |> array_sum(...);

Laravel'de bu operatoru ozellikle veri donusturme pipeline'larinda kullanmayi planliyorum:

$output = $rawInput
    |> trim(...)
    |> strtolower(...)
    |> fn($s) => preg_replace('/[^a-z0-9]+/', '-', $s)
    |> fn($s) => trim($s, '-');

Laravel'in kendi Pipeline sinifi daha karmasik is akislari icin hala gecerli ama basit donusturmeler icin pipe operator cok daha temiz.

Clone with

Immutable object'ler olusturmak kolaylasiyor:

class DateRange
{
    public function __construct(
        public readonly DateTimeImmutable $start,
        public readonly DateTimeImmutable $end,
    ) {}
}

$range = new DateRange(
    new DateTimeImmutable('2026-01-01'),
    new DateTimeImmutable('2026-12-31'),
);

// PHP 8.5 oncesi
$newRange = new DateRange(
    new DateTimeImmutable('2026-06-01'),
    $range->end,
);

// PHP 8.5 ile
$newRange = clone $range with {
    start: new DateTimeImmutable('2026-06-01'),
};

Bu ozellik Laravel'de request DTO'lari, value object'ler ve config objeleri icin ideal:

class SearchQuery
{
    public function __construct(
        public readonly string $term,
        public readonly int $page = 1,
        public readonly int $perPage = 15,
        public readonly string $sortBy = 'created_at',
    ) {}
}

$query = new SearchQuery(term: 'laravel');
$page2 = clone $query with { page: 2 };
$sorted = clone $query with { sortBy: 'title', page: 1 };

Locale-Independent Float to String

PHP'de (string) 1.5 ifadesi locale'e gore "1,5" veya "1.5" donebiliyordu. PHP 8.5 ile bu her zaman "1.5" donecek (nokta ile). Bu degisiklik ozellikle JSON response'lar ve API entegrasyonlarinda sessiz bug'lari onleyecek.

// PHP 8.5 oncesi - locale TR_tr ise
setlocale(LC_NUMERIC, 'tr_TR.UTF-8');
echo (string) 3.14; // "3,14" - JSON bozulabilir!

// PHP 8.5 ile
echo (string) 3.14; // Her zaman "3.14"

Bu Ozellikler Gunluk Laravel Kodumu Nasil Degistirdi?

PHP 8.4'e gectigimden beri en cok property hook'lari ve asymmetric visibility'yi kullaniyorum. Ozellikle servis siniflarinda ve DTO'larda kod cok daha temiz hale geldi.

Onceki yaklasim:

class OrderSummary
{
    private float $subtotal;
    private float $taxRate;

    public function __construct(float $subtotal, float $taxRate = 0.20)
    {
        $this->subtotal = $subtotal;
        $this->taxRate = $taxRate;
    }

    public function getSubtotal(): float
    {
        return $this->subtotal;
    }

    public function getTax(): float
    {
        return $this->subtotal * $this->taxRate;
    }

    public function getTotal(): float
    {
        return $this->subtotal + $this->getTax();
    }
}

PHP 8.4 ile ayni sinif:

class OrderSummary
{
    public function __construct(
        public private(set) float $subtotal,
        private float $taxRate = 0.20,
    ) {}

    public float $tax {
        get => round($this->subtotal * $this->taxRate, 2);
    }

    public float $total {
        get => $this->subtotal + $this->tax;
    }
}

$order = new OrderSummary(subtotal: 100.00);
echo $order->total; // 120.00
echo $order->tax;   // 20.00

Daha az boilerplate, daha okunakli, daha guvenli. Yeni array fonksiyonlari da Collection import etmek istemedigim helper fonksiyonlarda cok isime yariyor.

Gecis Stratejisi

Projelerinizi PHP 8.4'e gecirmek icin:

  1. composer.json'da "php": "^8.4" olarak guncelleyin
  2. phpstan veya psalm ile static analysis calistirin
  3. Deprecated fonksiyonlari (ozellikle implode arguman sirasi, utf8_encode/decode gibi) temizleyin
  4. CI/CD pipeline'da PHP 8.4 image kullanin
  5. Yeni ozellikleri kademeli olarak uygulayin, buyuk refactor yerine yeni kod yazarken kullanin
# GitHub Actions'da PHP 8.4
- name: Setup PHP
  uses: shivammathur/setup-php@v2
  with:
    php-version: '8.4'
    extensions: mbstring, xml, bcmath, redis

Sonuc

PHP 8.4 production-ready ve hemen kullanilabilir durumda. Property hook'lari ve asymmetric visibility tek basina gecis icin yeterli sebep. PHP 8.5'teki pipe operator ve clone with ise 2025 sonunda Laravel projelerimizde kodun okunabilirligini bir ust seviyeye tasiyacak. Benim onerim: PHP 8.4'e hemen gecin, yeni ozellikleri yeni yazdiginiz kodda kullanin ve 8.5 ciktiginda hazir olun.