PHP 8.1: New in Initializers
PHP 8.1 adds support for using the new expression as a default value in constructors, property promotions, static variables and global constants, enabling objects to be instantiated directly in initializer syntax while preserving lazy construction semantics.
PHP 8.1 introduces “new in initializers”, a feature that permits the new expression to be used as a default value for constructor parameters, promoted properties, static variables and global constants, bringing object instantiation directly into initializer syntax.
In a state‑machine example, the constructor can declare a property with a default object: private ?State $state = null and then assign $this->state ??= new InitialState(); . This mirrors the ability to set primitive defaults, but now works for objects as well.
<code>class MyStateMachine {
public function __construct(
private ?State $state = null,
) {
$this->state ??= new InitialState();
}
}</code>Object defaults can also be expressed directly in the parameter list:
<code>class MyStateMachine {
public function __construct(
private State $state = new InitialState(),
) {}
}</code>The RFC behind the feature states that new may be used in parameter default values, attribute arguments, static variable initializers, and global constant initializers. This extends to property promotion parameters, enabling patterns such as attribute‑based validation:
<code>class CreateEmailsRequest extends FormRequestData {
#[ValidArray(
email: [new Required, new ValidEmail],
name: [new Required, new ValidString],
)]
public array $people;
}</code>Prior to PHP 8.1 this was impossible because new expressions were not allowed in property defaults. The feature is lazy: objects are only created when the initializer is actually evaluated. For example, constructing new MyStateMachine(new DraftState()) does not instantiate InitialState , but calling new MyStateMachine() does.
There are restrictions: the initializer cannot contain variables, spread operators, anonymous classes, etc. Also, new cannot be used as a default value for a regular class property (non‑promoted) because of potential side effects during serialization.
When used with property promotion, the compiler rewrites the code so that the default value is applied in the constructor parameter, not in the property definition, avoiding those side effects.
Overall, “new in initializers” is a welcomed addition that simplifies object‑oriented code by reducing boilerplate while keeping object creation under control.
php中文网 Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.