← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

new in Initializers (PHP 8.4)

php PHP 8.4+ Intermediate

Also Known As

new in defaults new in initializers PHP 8.4 new expression

TL;DR

PHP 8.4 allows 'new ClassName()' expressions in default parameter values, attribute arguments, and static property initialisers — removing the need for null defaults combined with late assignment in constructors.

Explanation

PHP previously required that default parameter values, attribute arguments, and property initialisers be compile-time constants — scalar values, arrays, class constants, and null. Creating a default object value required a null default and manual assignment in the constructor body. PHP 8.4 allows 'new' expressions in these positions. 'function foo(Logger $log = new NullLogger())' is now valid. The object is created fresh for each call where the default is needed. This also works in property promotion: 'public function __construct(private Logger $log = new NullLogger()) {}' — clean null-object pattern without boilerplate.

Common Misconception

The default object is shared across all calls like a static variable. It is not — 'new NullLogger()' in a default creates a fresh instance for each invocation that uses the default. This is the opposite of a singleton.

Why It Matters

This feature eliminates a common boilerplate pattern: nullable parameters with manual instantiation. The null object pattern — where you provide a 'do nothing' default implementation — becomes a one-liner. Code that previously required three or four lines (nullable param + docblock + null check in body + assignment) now expresses intent cleanly in the signature.

Common Mistakes

  • Using new in initializers in PHP < 8.4 — parse error; check version before adopting.
  • Expecting the same instance to be reused across calls — each call that triggers the default creates a new object.
  • Using new with classes that have constructor side effects (DB connections, file handles) as defaults — the side effect runs on every call that omits the argument.
  • Forgetting this works in attribute arguments too — attribute classes that accept object dependencies can now have clean defaults.

Code Examples

✗ Vulnerable
<?php
// ❌ Pre-8.4 null default + manual instantiation boilerplate
class OrderService
{
    private Logger $logger;
    private Cache $cache;

    public function __construct(
        ?Logger $logger = null,
        ?Cache $cache = null
    ) {
        $this->logger = $logger ?? new NullLogger();
        $this->cache  = $cache  ?? new ArrayCache();
    }
}
✓ Fixed
<?php
// ✅ PHP 8.4 — new in initializers, clean constructor promotion
class OrderService
{
    public function __construct(
        private Logger $logger = new NullLogger(),
        private Cache  $cache  = new ArrayCache(),
    ) {}
}

// Also valid in standalone functions
function sendNotification(
    string $message,
    Mailer $mailer = new SmtpMailer(),
): void {
    $mailer->send($message);
}

Added 23 Mar 2026
Views 20
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S
Amazonbot 1
No pings yesterday
Amazonbot 7 Perplexity 2 Google 2 ChatGPT 1 Ahrefs 1
crawler 12 crawler_json 1
DEV INTEL Tools & Severity
⚙ Fix effort: Low
⚡ Quick Fix
Replace 'function log(?Logger $l = null) { $l ??= new NullLogger(); }' with 'function log(Logger $l = new NullLogger()) {}' in PHP 8.4+.
📦 Applies To
PHP 8.4+ web cli

✓ schema.org compliant