PHP 8: Constructor property promotion

Personally, I use value objects and data transfer objects all the time in my projects. I even wrote a dedicated post on how to treat data in our code a while back.

Naturally, I'm very happy with the constructor property promotion RFC, it's passed and will be added in PHP 8 . You see, this feature reduces a lot of boilerplate code when constructing simple objects such as VOs and DTOs.

In short: property promotion allows you to combine class fields, constructor definition and variable assignments all into one syntax, in the construct parameter list.

So instead of doing this:

You would write this:

Let's look at how it works!

# How it works

The basic idea is simple: ditch all the class properties and the variable assignments, and prefix the constructor parameters with public , protected or private . PHP will take that new syntax, and transform it to normal syntax under the hood, before actually executing the code.

So it goes from this:

And only executes it afterwards.

Note by the way that the default value is not set on the class property, but on the method argument in the constructor.

# Promoted property properties

So let's look at what promoted properties can and can't do, there's quite a lot of little intricacies worth mentioning!

# Only in constructors

Promoted properties can only be used in constructors. That might seem obvious but I thought it was worth mentioning this, just to be clear.

Noticed a tpyo? You can submit a PR to fix it. If you want to stay up to date about what's happening on this blog, you can subscribe to my mailing list : send an email to [email protected] , and I'll add you to the list.

# No duplicates allowed

You're not able to declare a class property and a promoted property with the same name. That's also rather logical, since the promoted property is simply transpiled to a class property at runtime.

# Untyped properties are allowed

You're allowed to promote untyped properties, though I'd argue that these days with modern PHP , you're better off typing everything.

# Simple defaults

Promoted properties can have default values, but expressions like new … are not allowed.

# Combining promoted- and normal properties

Not all constructor properties should be promoted, you can mix and match.

I'd say: be careful mixing the syntaxes, if it makes the code less clear, consider using a normal constructor instead.

# Access promoted properties from the constructor body

You're allowed to read the promoted properties in the constructor body. This can be useful if you want to do extra validation checks. You can use both the local variable and the instance variable, both work fine.

# Doc comments on promoted properties

You can add doc comments on promoted properties, and they are still available via reflection.

# Attributes

Just like doc blocks, attributes are allowed on promoted properties. When transpiled, they will be present both on the constructor parameter, as well as the class property.

Will be transpiled to:

# Not allowed in abstract constructors

I didn't even know abstract constructors were a thing, but here goes! Promoted properties are not allowed in them.

# Allowed in traits

On the other hand, they are allowed in traits. This makes sense, since the transpiled syntax is also valid in traits.

# var is not supported

Old, I mean, experienced PHP developers might have used var in a distant past to declare class variables. It's not allowed with constructor promotion. Only public , protected and private are valid keywords.

# Variadic parameters cannot be promoted

Since you can't convert to a type that's array of type , it's not possible to promote variadic parameters.

Still waiting for generics…

# Reflection for isPromoted

Both ReflectionProperty and ReflectionParameter have a new isPromoted method to check whether the class property or method parameter is promoted.

# Inheritance

Since PHP constructors don't need to follow the declaration of their parent constructor, there's little to be said: inheritance is allowed. If you need to pass properties from the child constructor to the parent constructor though, you'll need to manually pass them:

That's about it for property promotion! I for sure will use them, what about you? Let me know via Twitter or e-mail !

PHP 8.0: Class constructor property promotion

Constructor Property Promotion is a new syntax in PHP 8 that allows class property declaration and constructor assignment right from the constructor.

A typical class that declares a property, and then assigns a value to it in the class constructor is quite verbose.

With the Constructor Property Promotion syntax, the class declaration above can be minimized to avoid boilerplate:

This results in a much simplified and minimal syntax that is functionally identical to the verbose class declaration:

What it does

Constructor Property Promotion is a shorthand syntax to declare and assign class properties from the constructor . This avoids having to type the class property name from four times to just once , and property type from twice to just once .

Your constructor can still run additional code within the constructor. Properties will be assigned before the rest of the constructor code is executed .

If you change the constructor argument, you need to re-assign it to the class property :

AST and Reflection

Constructor Property Promotion is not internally handled as an Abstract Syntax Tree transformation. This means if you inspect the AST (with an extension such as php-ast ), you will still see the code as written with property visibility modifiers right in the constructor.

Reflection API , it will seamlessly return information about both standard and constructor-promoted properties all the same.

In Reflection API, ReflectionProperty and ReflectionParameter classes will have a new method isPromoted to determine if the parameter/property was declared in a constructor.

Mixing constructor properties with standard properties

A class is allowed to have constructor-promoted properties and standard properties:

However, note that the same property must not be declared as a standard property and a constructor-promoted property .

Property Type is not required

It is possible to use Typed Properties and un-typed properties, although it's often a good idea to always strict type class properties.

In the example above $uid will be a class property, but without a type declared to it.

Nullable types are supported, but not implicit syntax

Nullable properties can be promoted at constructor, however, the PHP 7.0-style nullable types are not supported.

While the syntax above is allowed, implicit declaration of types (without the ? prefix, but = null default value) is not allowed:

Both property promotions above are not allowed because they are implicitly declaring nullable types, but without the ?string syntax. Although it works, this practice is frowned upon.

No duplicate properties

It is not allowed to duplicate a property with explicit declaration and constructor property promotion.

The following code is not allowed:

Not supported in interfaces and abstract classes, allowed in traits

Constructor Properties cannot be used in interfaces because they simply don't allow properties in the first place.

Not allowed:

Abstract classes can have constructor properties promoted, but not if the constructor itself is marked abstract .

Traits can contain both properties and methods, including constructors. This means it is possible for a trait for make use of Constructor Property Promotion too.

var is not allowed

The legacy syntax of declaring a property with var keyword is not allowed. All constructor-promoted properties must be declared with public , protected , or private visibility modifiers.

The following code is not valid:

callable type is not allowed

callable is a valid type in PHP, but it is not allowed as a property type. Thus, it is not allowed to declare a constructor property with type callable either:

Only constructor supports property promotion

It probably goes without saying, but only the __construct method can have properties promoted. Other methods cannot:

Backwards compatibility impact

Constructor Property Promotion is a syntax change in PHP 8, and so it's not possible to backport this feature to older PHP versions. If you use Constructor Property Promotion, that code will not be compatible with PHP 7 and older versions.

Attempting to run constructor-promoted classes will throw a parse error:

Derick Rethans interviewed Nikita Popov (author of the RFC) in PHP Internals News podcast, which you can list here .

RFC Discussion Implementation

  • PHP Tutorial
  • PHP Calendar
  • PHP Filesystem
  • PHP Programs
  • PHP Array Programs
  • PHP String Programs
  • PHP Interview Questions
  • PHP IntlChar
  • PHP Image Processing
  • PHP Formatter
  • Web Technology
  • How to show All Errors in PHP ?
  • PHP Filter and Filter Constant
  • PHP program to swap two numbers
  • Differences between API Testing and Unit Testing
  • How to delete an element from an array using JavaScript ?
  • PHP Forms Validate URL
  • How to Encrypt and Decrypt a PHP String ?
  • Program to find the number of days between two dates in PHP
  • What is the differences between array_merge() and array_merge_recursive() functions in PHP ?
  • What is the difference between for and Foreach loop in PHP ?
  • Difference between require() and include() in PHP
  • How to Start and Stop a Timer in PHP ?
  • How to install PHP in windows 10 ?
  • What are the different scopes of variables in PHP ?
  • What's the difference between \n and \r\n in PHP ?
  • Write a program to get second highest number in an array using PHP ?
  • What is the difference between count() and sizeof() functions in PHP ?
  • What are the differences between array_keys() and array_key_exists() in PHP ?
  • How to remove duplicate values from array using PHP ?

Constructor Property Promotion in PHP 8

Constructor Property Promotion is a simple shorthand syntax to declare and assign class properties from the constructor. It basically tells the way data has to be treated in code. Constructor Property Promotion is a new syntax provided in the newer version of PHP 8 that allows class property declaration and constructor assignment, variable assignment right from the constructor without getting in the condition of boilerplate code. This avoids having to type the class property name and property type from many to just once. It also avoids using repeated types. Promoted properties can only be used in constructors. Properties will be assigned before the rest of the constructor code is executed.

Note: Not all constructor properties should be promoted, you can mix and match with promoted and normal properties, and it’s absolutely ok to combine them. Promoted properties mostly improve code quality. The below example illustrates the basic syntax for the Constructor Property in PHP 8:

Example 1: This example describes the basic usage of the Constructor Property Promotion in PHP 8.

Example 2: After the latest update in PHP version 8, it provides Constructor Property Promotion of simpler syntax.

Example 3: This is another example of a constructor class in PHP.

Example 4: The above code is using the constructor property promotion.

Demerits of Constructor Property Promotion:

  • Abstract classes can have constructor properties promoted, but they cannot have it if the constructor is marked abstract. It is not usable in all situations
  • var is not allowed with the promoted property.
  • A callable type is not allowed and a nullable type cannot be implicit with a promoted property.

Please Login to comment...

Similar reads.

author

  • PHP-Questions
  • Web technologies
  • Web Technologies
  • 10 Ways to Use Slack for Effective Communication
  • 10 Ways to Use Google Docs for Collaborative Writing
  • NEET MDS 2024 Result: Toppers List, Category-wise Cutoff, and Important Dates
  • NDA Admit Card 2024 Live Updates: Download Your Hall Ticket Soon on upsc.gov.in!
  • 30 OOPs Interview Questions and Answers (2024)

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

Constructor Property Promotion in PHP 8.0

Constructor Property Promotion in PHP 8.0

  • January 17, 2021 (January 23, 2023)

Properties are class member variables that store values like strings, integers, boolean, etc. We can set properties via class constructor, setter method or directly if property is public.

When we set properties via constructor, the class can be written as follows:

As we can see, properties names were repeated four times: in class property declaration, in constructor parameters, and two times when assigning property value in the body of the constructor.

Since PHP 8.0, we can use constructor property promotion. This is a new syntax that allows to combine properties declaration, constructor parameters and properties assignments in one place.

We can rewrite the previous code as follows:

As we can see, properties were declared and assigned via class constructor. We need to write properties names just once instead of four times.

There are some notes for constructor property promotion.

The visibility of a property

Property is promoted when it declared in the constructor with visibility. We can use public , protected or private visibility keywords. The visibility of properties don't need to be the same, it can be mixed.

Note: $email is just constructor parameter and not promoted property because visibility is not specified.

Standard constructor parameters

Promoted properties can be declared together with standard constructor parameters. The order doesn't matter.

No duplicates

Property cannot be declared in the constructor as promoted property if property already declared in the class.

Reassign promoted property

Promoted properties can be reassigned in the body of the constructor or do other logic.

Default value

Promoted property can be declared with default value.

The var keyword

To declare property using legacy syntax with var keyword is not allowed for property promotion.

The type of a property

To be property promoted, the type of property is not required.

The callable type

The callable type is not allowed as a property type. So, it is not allowed for property promotion too.

Variadic parameters

Variadic parameters cannot be used for property promotion.

Nullable types

Nullable types must be explicitly declared by specifying ? before type definition.

Implicit nullable types (without ? , but has null as default value) are not supported for property promotion.

Only constructor

Promoted properties can be declared only in the constructor. In other methods cannot.

Abstract constructor

Promoted properties cannot be declared in an abstract constructor.

Interface constructor is considered as abstract. So promoted properties cannot be declared in the interface constructor.

Trait constructor

It is allowed to declare promoted properties in the trait constructor.

Doc comments

Doc comments can be added on promoted properties and can be retrieved using the Reflection API.

Attributes are allowed on promoted properties.

Generate Random String using Randomizer Class in PHP 8.3

Leave a Comment

Your email address will not be published.

Save my name, email in this browser for the next time I comment.

  • Découvre nos formations !
  • My Favourite Books
  • Who's Mindsers?

Constructor property promotion in PHP 8

Constructor property promotion in PHP 8

23 juil. 2022 • 3 min read

This post is free for all to read thanks to the investment Mindsers Club members have made in our independent publication. If this work is meaningful to you, I invite you to join the club today.

If there is one redundant and boring thing in object-oriented programming, it is the definition of object constructors. In most cases, the majority of the code written is actually information that the interpreter or compiler could understand on its own.

What I have just stated is not very nuanced, it is true. But if I go through the codebases of my previous projects, the majority of the constructors I have written are only used to initialize instance variables (properties).

Let's take an example in PHP to illustrate this:

Here is a typical example of everything I described above. There are three properties that are repeated as arguments to the constructor and again twice at assignment time inside the constructor. Types are also repeated twice.

It seems to see almost the same code three times. It's boring to read, but even more tiring to write or maintain: this way of doing things increases the risk of error. Why? If I change any of the instance properties, I definitely need to remember to change the constructor property declarations and/or assignments as well.

PHP 8 provides a solution to this problem through the promotion of constructor properties.

The two examples are identical. But watch how promoted properties help make code simpler, more readable, and smarter. All the information we need to understand the code is on the same line, not split into three separate places.

Again, this is not a breakthrough feature or something truly new. Other languages like TypeScript have already had this feature for a while.

Not usable in all situations

Some of you may have already thought of this, but there are cases where using constructor property promotion is not going to be possible.

This functionality means: creating instance variables automatically and assigning them. Which is not possible in an abstract constructor, for example.

Another case where this functionality is not usable is the case of callables. The callable type is not supported for method properties. It is therefore impossible to promote a callable property since it does not exist.

I would also add that promoted properties cannot be used with implicitly nullable types. Or rather, a nullable type cannot be implicit with a promoted property.

As long as you explicitly indicate that the property can be null , PHP won't mind.

Promoted properties improve code quality

I've used it often in TypeScript, and I find promoting constructor properties really useful in my daily life as a developer. Let me explain: first, I write three times less code. Then, my reading and understanding of the code is easier for a given instance variable.

But this method also gives me information about the other properties of the constructor. In the example above, did you notice the $desc property? We don't use constructor property promotion for it, which gives me another piece of information: $desc is not a classic case of an instance variable, the developer had to do something else with it, and it might be interesting to watch what it's all about.

It's contextual: since the developer who wrote the code used promoted properties, why didn't he promote all the properties? Probably because he had no choice. Perhaps he had particular tests to do on this property. Or, like in our example, maybe it needed to pass it to the parent class. It makes the code smarter, but it also makes the reading of the code smarter by indicating the points of attention to be had.

And as it is contextual, as you can imagine, the reasoning that I have just described will not work every time. If none of the properties are promoted, that doesn't necessarily mean that all properties of that constructor are special cases. Maybe the developer who wrote the code doesn't yet know that the promoted properties exist, maybe he doesn't want to use this feature, or maybe his code was written before the arrival of PHP 8. Anyway, you get the idea.

I will end this article by reminding that Promoted Properties is a lazy feature and developer being lazy, I am sure you will all be happy to adopt it in your future projects. In the meantime, here's some reading:

  • Decouple your code!
  • PHP8's named arguments

Join 250+ developers and get notified every month about new content on the blog.

No spam ever. Unsubscribe in a single click at any time.

If you have any questions or advices, please create a comment below! I'll be really glad to read you. Also if you like this post, don't forget to share it with your friends. It helps a lot!

By clicking "Allow all", you agree to the storing of cookies on you device to enhance site navigation, analyse site usage, and assist in our marketing effort.

Allow all Deny all

phpGrid – PHP Datagrid

PHP 8: Constructor property promotion

php 8 banner

It’s typical for constructor arguments to be allocated to a property in the constructor but never used. PHP 8 added constructor promotion as a convenient shorthand for such scenario.

Below is a typical constructor pre PHP 8:

It seems just repetitive work with no real benefits. Thankfully, starting PHP 8.0, when a visibility modifier is included in a constructor argument, PHP treats it as both an object property and a constructor argument, and assigns the argument value to the property.

So you can now write this in PHP 8:

With much cleaner and shorter syntax, property promotion allows you to integrate class fields, constructor definitions, and variable assignments – all into a single syntax.

The Promoted properties can have default value

It’s ok to combine promoted and normal properties.

It’s important to note that you can’t have the same name for a class property and a promoted property.

Do not use ‘var’

Finally, when declaring class variables for constructor property promotion, do not use ‘var’. Only the terms “public,” “protected,” and “private” are permitted.

So the following is not a valid constructor property promotion:

That’s all there is to it. The constructor property promotion makes your code cleaner, shorter, and more awesome! Learn to start using it today.

Recommended read: https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion

Related Posts

You can now directly manipulate individual column properties without using helper set_col_* functions such as set_col_format()…

In our phpGrid examples, we've seen some code with 'weird' syntax such as in event handler…

* CRUD PHP Datagrid feature is only available in paid versions.   The PHP datagrid is…

How-To Geek

Constructor property promotion in php 8.

Constructor property promotion is a new PHP 8 convenience feature which helps you minimise code repetition.

Quick Links

A traditional class, adding constructor property promotion, a closer look, using with a constructor body, combining with regular properties and parameters, use with attributes, possible gotchas.

Constructor property promotion is a new PHP 8 convenience feature which helps you minimise code repetition. It lets you combine the definition and initialisation of properties into a single constructor statement.

Constructor property promotion (CPP from hereon) is most useful in the context of value objects. These tend to be simple classes which describe a data structure. Here's what one might look like in PHP 7.4:

class BlogPost {

protected string $Title;

protected string $Content;

protected DateTimeImmutable $PostedDate;

public function __construct(

string $Title,

string $Content,

DateTimeImmutable $PostedDate) {

$this -> Title = $Title;

$this -> Content = $Content;

$this -> PostedDate = $PostedDate;

We've created a reasonably lengthy class, despite having only three properties! Each property name occurs four times, with the typehints being written twice. If you needed to amend one of the properties, or add another, you'd be touching three lines of code.

Here's the same example, rewritten to use CPP in PHP 8:

protected string $Title,

protected string $Content,

protected DateTimeImmutable $PostedDate) {}

By using CPP we've drastically cut the size of our class. You'd only need to add or alter one line of code when working with this class' properties.

CPP combines property definition with the constructor's parameter list. To create a promoted property, prefix its name with a class visibility modifier -

Once promoted, the property behaves like any other class property. You can access it within the class using

or externally (if it's a

property). Internally, PHP's simply transforming the compact syntax into the much lengthier version supported by PHP 7.

You don't have to use typehints with promoted properties - it's acceptable to write

, for example. You can set default values using the same syntax as a regular constructor parameter (

Your constructor won't always be quite as simple as our example. You might need to perform some validation checks or transform a value.

You can still write a constructor body when using CPP. You'll be able to access the values of your promoted properties either as the promoted instance variable or using the local variable:

public function __construct(protected string $Title) {

if (!$this -> Title) {

throw new InvalidArgumentException("Title cannot be empty.");

if (!$Title) {

Whichever approach you choose, the variable or the property, you'll be working with the same value. PHP simply hides the

line you'd normally be writing manually.

You can freely mix promoted properties with regular property definitions. In addition, you can combine promoted and non-promoted properties in your constructor parameters.

public ?DateTimeImmutable $PostedDate = null;

public function __construct(public string $Title, bool $isPosted=true) {

if ($isPosted) $this -> PostedDate = new DateTimeImmutable();

You should be careful when mixing these syntaxes together. Promoted properties can easily be overlooked when skimming the code, especially if preceded by regular class property definitions. If your class already possesses several properties using the traditional form, using the new syntax for one extra addition might not be the best approach for that file.

One of PHP 8's other new features was attributes. These allow you to annotate extra metadata against entities in your codebase.

Attributes are fully supported on promoted properties. As it's ambiguous whether the attribute applies to a property definition or a method parameter, PHP will apply it to both.

That means you'll get the same value back whether you're inspecting the property or the constructor parameter. This flexible approach ensures you don't lose any functionality of attributes by adopting constructor property promotion.

Promoted properties - and constructor arguments which promote a property - behave intuitively when introspected via the Reflection APIs. Reflection looks at promoted properties in their post-transpilation state, so they appear identical to an explicitly declared property.

classes have new

methods to let you check whether they were involved with CPP. Generally, this shouldn't need to be considered though, unless you're writing a tool which wants to replicate the exact source structure.

You cannot declare duplicate class and promoted property names. The following example would result in a runtime error:

public string $Title;

public function __construct(public string $Title) {}

This is because PHP doesn't really do anything special with promoted property definitions. It simply transpiles your terse source code into the PHP 7.4 style. This would result in two

lines, which has always been forbidden.

There are other cases where CPP might result in an error. Promoted properties are forbidden in abstract classes, although they can be used in traits. You're unable to use the

type with them because it's not supported for property definitions. Finally, there's no support for variadic parameters (e.g. 

) because the property would end up being an

instances, not a

Constructor property promotion makes it much quicker to write new value objects in your codebase. It can cut the number of lines by up to two thirds! CPP also helps you DRY (Don't Repeat Yourself) your code by avoiding the unsightly repetition of typehints and property names which PHP 7.4 required.

Adopting CPP is optional and won't always make sense for existing classes. It's best suited to simple struct-like classes, where you want to provide strong typing to data that's going to be passed through your codebase.

  • Multiframework
  • Multisite/Apps
  • Sustainability
  • Partner Portal Log in to the Agency Partner Portal.
  • Find an agency partner
  • Agency Partner Program
  • Ecommerce for agency partners
  • Agency partner video series
  • White-label PaaS
  • Community Find answers, tips and best practices. Everything you need to know to get started with Platform.sh
  • Resource Library Never stop learning with Platform.sh ebooks, white papers, and webinars.
  • Case Studies
  • Security & Compliance
  • Trust Center
  • Cloud Regions
  • Join our Mailing List
  • Leadership & Board
  • Read our Reviews

php 8 constructor assignment

  • Product Updates
  • Engineering
  • Customer Stories

Cover image

PHP 8.0 feature focus: Constructor Property Promotion

Larry Garfield

The last post talked about how PHP 8.0 makes PHP faster. Today, we'll look at a way that it will make you faster.

Perhaps the largest quality-of-life improvement to PHP 8.0 is Constructor Property Promotion. The syntax has been borrowed largely from Hack, Facebook's PHP fork, although it exists in other languages like TypeScript and Kotlin with various syntaxes.

It's easiest to explain with an example. Consider your typical service class in a modern application:

That class has three dependencies. Each one has to be named four times : once to declare the property, once for the constructor parameters, once when referencing the parameter, and once when referencing the property. That is ridiculously verbose, and while many IDEs have some code completion features to help, it's still a pain. I have known people to avoid classes and dependency injection purely because of that verbosity.

As of PHP 8.0, that can all be collapsed down to this:

Moving the visibility marker into the constructor declaration tells PHP "this parameter is also a property, you should assign the passed value to it." The effect at runtime is exactly the same as the first example, but it requires one-fourth as much typing. That's a win.

(Also, see that trailing comma in the parameter list? This feature is exactly why it was added.)

It's still entirely possible to declare additional properties the traditional way, and the constructor can also still have a body. In this example the body is empty, but if there is more work to do in the constructor than "assign stuff to properties," that code can still be included and will execute after the assignment (or "promotion") is done.

In practice, the vast majority of classes I've written in the last few years have had such "boring" constructors, which means property promotion will dramatically cut down the amount of typing needed in the future.

Valuing your data

Constructor property promotion is even more valuable on value objects. (Value objects and service objects should make up the vast majority of your classes; there are only a tiny few other good models in PHP.) Many value objects (or Data Transfer Objects, or various other names they go by) are in practice little more than structs: a collection of named properties with, possibly, getters and setters on them. In that case, the entire class can now be reduced to little more than a constructor:

Making the properties public may be uncomfortable for some. In general, I would argue that for an internal (not part of the API) object it's fine, but for an object that is part of a public API making a series of getter methods and making the properties private is worthwhile. It's still less typing than it was, and it's also faster and far more memory efficient than using arrays .

It's also entirely allowed to have only some constructor parameters promoted and not others. The ones that are not will behave the same as they always have.

As usual, there are a few caveats.

  • The visibility keywords only apply for constructors; using them in any other function or method signature is an error.
  • A property may not be defined both in the constructor signature and on its own. If the property needs more than can be included in the signature, do it the old style way. That still works fine.
  • Properties cannot be typed as callable (for implementation complexity reasons we won't get into here), so neither can constructor promoted properties. They can be left untyped, however.
  • Variadic arguments cannot be promoted, as that makes the types harder to juggle.

Once again, we have Nikita Popov to thank for this RFC , although the instigation was a blog post earlier this year by yours truly, so I'll claim a 0.1% credit.

We're in the home stretch. Stay tuned for next week where we discuss PHP 8.0's most contentious, and most anticipated, new feature.

You can try out pre-release copies of PHP 8.0 today on Platform.sh, with just a one-line change. Give it a whirl, and let us know what your favorite features are.

Get the latest Platform.sh news and resources

Related content.

A festive treat: PHP 8.3 is already available on Platform.sh

A festive treat: PHP 8.3 is already available on Platform.sh

Blackfire is now even closer to home!

Blackfire is now even closer to home!

PHP 8.2 lays new ground on Platform.sh

PHP 8.2 lays new ground on Platform.sh

Leader Winter 2023

  • « Autoloading Classes
  • Visibility »
  • Classes and Objects

Constructors and Destructors

Constructor.

PHP allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.

Note : Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct() within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method (if it was not declared as private).

Example #1 Constructors in inheritance

Unlike other methods, __construct() is exempt from the usual signature compatibility rules when being extended.

Constructors are ordinary methods which are called during the instantiation of their corresponding object. As such, they may define an arbitrary number of arguments, which may be required, may have a type, and may have a default value. Constructor arguments are called by placing the arguments in parentheses after the class name.

Example #2 Using constructor arguments

If a class has no constructor, or the constructor has no required arguments, the parentheses may be omitted.

Old-style constructors

Prior to PHP 8.0.0, classes in the global namespace will interpret a method named the same as the class as an old-style constructor. That syntax is deprecated, and will result in an E_DEPRECATED error but still call that function as a constructor. If both __construct() and a same-name method are defined, __construct() will be called.

In namespaced classes, or any class as of PHP 8.0.0, a method named the same as the class never has any special meaning.

Always use __construct() in new code.

Constructor Promotion

As of PHP 8.0.0, constructor parameters may also be promoted to correspond to an object property. It is very common for constructor parameters to be assigned to a property in the constructor but otherwise not operated upon. Constructor promotion provides a short-hand for that use case. The example above could be rewritten as the following.

Example #3 Using constructor property promotion

When a constructor argument includes a modifier, PHP will interpret it as both an object property and a constructor argument, and assign the argument value to the property. The constructor body may then be empty or may contain other statements. Any additional statements will be executed after the argument values have been assigned to the corresponding properties.

Not all arguments need to be promoted. It is possible to mix and match promoted and not-promoted arguments, in any order. Promoted arguments have no impact on code calling the constructor.

Note : Using a visibility modifier ( public , protected or private ) is the most likely way to apply property promotion, but any other single modifier (such as readonly ) will have the same effect.
Note : Object properties may not be typed callable due to engine ambiguity that would introduce. Promoted arguments, therefore, may not be typed callable either. Any other type declaration is permitted, however.
Note : As promoted properties are desugared to both a property as well as a function parameter, any and all naming restrictions for both properties as well as parameters apply.
Note : Attributes placed on a promoted constructor argument will be replicated to both the property and argument. Default values on a promoted constructor argument will be replicated only to the argument and not the property.

New in initializers

As of PHP 8.1.0, objects can be used as default parameter values, static variables, and global constants, as well as in attribute arguments. Objects can also be passed to define() now.

Note : The use of a dynamic or non-string class name or an anonymous class is not allowed. The use of argument unpacking is not allowed. The use of unsupported expressions as arguments is not allowed.

Example #4 Using new in initializers

Static creation methods

PHP only supports a single constructor per class. In some cases, however, it may be desirable to allow an object to be constructed in different ways with different inputs. The recommended way to do so is by using static methods as constructor wrappers.

Example #5 Using static creation methods

The constructor may be made private or protected to prevent it from being called externally. If so, only a static method will be able to instantiate the class. Because they are in the same class definition they have access to private methods, even if not of the same object instance. The private constructor is optional and may or may not make sense depending on the use case.

The three public static methods then demonstrate different ways of instantiating the object.

  • fromBasicData() takes the exact parameters that are needed, then creates the object by calling the constructor and returning the result.
  • fromJson() accepts a JSON string and does some pre-processing on it itself to convert it into the format desired by the constructor. It then returns the new object.
  • fromXml() accepts an XML string, preprocesses it, and then creates a bare object. The constructor is still called, but as all of the parameters are optional the method skips them. It then assigns values to the object properties directly before returning the result.

In all three cases, the static keyword is translated into the name of the class the code is in. In this case, Product .

PHP possesses a destructor concept similar to that of other object-oriented languages, such as C++. The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.

Example #6 Destructor Example

Like constructors, parent destructors will not be called implicitly by the engine. In order to run a parent destructor, one would have to explicitly call parent::__destruct() in the destructor body. Also like constructors, a child class may inherit the parent's destructor if it does not implement one itself.

The destructor will be called even if script execution is stopped using exit() . Calling exit() in a destructor will prevent the remaining shutdown routines from executing.

Note : Destructors called during the script shutdown have HTTP headers already sent. The working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache).
Note : Attempting to throw an exception from a destructor (called in the time of script termination) causes a fatal error.

php 8 constructor assignment

DEV Community

DEV Community

Nathanaël CHERRIER

Posted on Jul 23, 2022 • Originally published at mindsers.blog on Jul 23, 2022

Constructor property promotion in PHP 8

If there is one redundant and boring thing in object-oriented programming, it is the definition of object constructors. In most cases, the majority of the code written is actually information that the interpreter or compiler could understand on its own.

⚠️ Read more of my blog posts about tech and business on my personal blog ! ⚠️

In this series of articles, I come back with you on the new features of the latest version of PHP. Let's discover together what PHP version 8 has new to offer us and how it could be useful to us.

What I have just stated is not very nuanced, it is true. But if I go through the codebases of my previous projects, the majority of the constructors I have written are only used to initialize instance variables (properties).

Let's take an example in PHP to illustrate this:

Here is a typical example of everything I described above. There are three properties that are repeated as arguments to the constructor and again twice at assignment time inside the constructor. Types are also repeated twice.

It seems to see almost the same code three times. It's boring to read, but even more tiring to write or maintain: this way of doing things increases the risk of error. Why? If I change any of the instance properties, I definitely need to remember to change the constructor property declarations and/or assignments as well.

PHP 8 provides a solution to this problem through the promotion of constructor properties.

The two examples are identical. But watch how promoted properties help make code simpler, more readable, and smarter. All the information we need to understand the code is on the same line, not split into three separate places.

Again, this is not a breakthrough feature or something truly new. Other languages like TypeScript have already had this feature for a while.

Not usable in all situations

Some of you may have already thought of this, but there are cases where using constructor property promotion is not going to be possible.

This functionality means: creating instance variables automatically and assigning them. Which is not possible in an abstract constructor, for example.

Another case where this functionality is not usable is the case of callables. The callable type is not supported for method properties. It is therefore impossible to promote a callable property since it does not exist.

I would also add that promoted properties cannot be used with implicitly nullable types. Or rather, a nullable type cannot be implicit with a promoted property.

As long as you explicitly indicate that the property can be null , PHP won't mind.

Promoted properties improve code quality

I've used it often in TypeScript, and I find promoting constructor properties really useful in my daily life as a developer. Let me explain: first, I write three times less code. Then, my reading and understanding of the code is easier for a given instance variable.

But this method also gives me information about the other properties of the constructor. In the example above, did you notice the $desc property? We don't use constructor property promotion for it, which gives me another piece of information: $desc is not a classic case of an instance variable, the developer had to do something else with it, and it might be interesting to watch what it's all about.

It's contextual: since the developer who wrote the code used promoted properties, why didn't he promote all the properties? Probably because he had no choice. Perhaps he had particular tests to do on this property. Or, like in our example, maybe it needed to pass it to the parent class. It makes the code smarter, but it also makes the reading of the code smarter by indicating the points of attention to be had.

And as it is contextual, as you can imagine, the reasoning that I have just described will not work every time. If none of the properties are promoted, that doesn't necessarily mean that all properties of that constructor are special cases. Maybe the developer who wrote the code doesn't yet know that the promoted properties exist, maybe he doesn't want to use this feature, or maybe his code was written before the arrival of PHP 8. Anyway, you get the idea.

I will end this article by reminding that Promoted Properties is a lazy feature and developer being lazy, I am sure you will all be happy to adopt it in your future projects. In the meantime, here's some reading:

  • Decouple your code!
  • PHP8's named arguments

Top comments (0)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

sariah profile image

Top 10 Tools Every React Developer Needs in 2024

Sariah - Apr 3

arjuncodess profile image

Consistency Is All That Matters! Lessons from Atomic Habits 🌱🚀

Arjun Vijay Prakash - Apr 4

wydoinn profile image

Run LLMs Locally Using Ollama (Open Source)

Santhosh - Apr 5

prahladyeri profile image

Intro to DOMPDF - light and simple PHP library to generate PDF documents

Prahlad Yeri - Apr 5

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Amit Merchant Verified ($10/year for the domain)

A blog on PHP, JavaScript, and more

Constructor Property Promotion in PHP 8

June 9, 2020 · PHP

Wouldn’t it be nice if you don’t have to declare the class property over and over again just to use it across the class? Currently, you’d do it by first declaring it…

  • In the property declaration.
  • In the constructor parameters.
  • In the property assignment in the costructor body.

So, a class with properties declared would look like so.

Things are getting interesting in PHP 8 for this scenario. According to this RFC (which is accepted), Constructor Property Promotion is coming in PHP 8.

Constructor Property Promotion

With the use of constructor property promotion, it will be really easy to declare class properties by just declaring and defining properties all in one place.

Let’s modify the previous example to see how it would look like when using constructor property promotion.

As you can see, using construstor property promotion, there are couple of benefits at our disposal.

  • There’s no need to declare properties in the class and defining them into the constructor body.
  • The syntax is more shorter and less error-prone as you don’t have to maintain same property at three different places!

Here, when a method parameter is prefixed with one of the visibility keywords public, protected or private, it is considered to be “promoted” . When a parameter is promoted, a property with the same name will be added, and a forwarding assignment to that property included in the body of the constructor.

Rules on using constructor property promotion

There are some places where you won’t be able to use constructor property promotion.

  • It can only be occurred in class constructors and not in other class methods.
  • It can’t be occurred in non-class based methods.
  • It can’t be occurred in abstract class constructors or in interfaces.
  • Properties with callable types are not eligible to be promoted.
  • If the property is nullable, nullability must be explicitly declared using ? like so.
  • Variadic parameters cannot be promoted. So, the following would be invalid.
  • Promoted and non-promoted paramters can be used simultaneouly. So, following is absolutely valid.

You can learn more about this feature over here .

More in PHP 8 The mixed type New string functions Non-capturing exception catches Nullsafe operator Union types

PHP 8 in a Nutshell book cover

» Share: Twitter , Facebook , Hacker News

Like this article? Consider leaving a

Caricature of Amit Merchant sketched by a friend

👋 Hi there! I'm Amit . I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.

More on similar topics

How to return multi-line JavaScript code from PHP

What's new in PHP 8.4

Tools to make your developer experience better in PHP

Using Google's Gemini AI in PHP

Awesome Sponsors

Download my eBook

PHP 8 in a Nutshell

Recommendation(s)

Get the latest articles delivered right to your inbox!

No spam guaranteed.

Follow me everywhere

More in "PHP"

Convert HTML to PDF using Headless Chrome in PHP

Recently Published

Talk to websites and PDFs with this free Chrome Extension NEW

RunJS — A JavaScript Playground on your desktop

The fluent data helper in Laravel

Spicing up text with text-emphasis in CSS

Comparing a value against multiple columns the easy way in Laravel

Top Categories

Constructor Property Promotion In PHP 8.0

Constructor Property Promotion is a feature in PHP 8.0 related to constructor arguments. Let’s see this feature in this article. 

To describe the Class Constructor Property Promotion in PHP look at this example:

In this class we have three properties for the product, ($id, $name, $price). The constructor also accepts these argument so whenever creating any instance of this class you have to provide these arguments. This is a common example we usually see a lot. 

By using the Constructor Property Promotion we can rewrite this example in a simple way:

As shown in the code the Property Promotion feature allow us to do class property declaration and property assignment right from the constructor. So this code is pretty similar to the original code. This enables us shorten big classes that contain many properties. 

How this works?

Typically when a constructor argument includes a modifier such as public, private, protected, etc, PHP interpreter will interpret it as an object property and a constructor argument, then assign the argument value to the property. 

Note that this feature from PHP 8.0 and later so you can’t use it in PHP < PHP 8.0

Promoted Property & Modifiers

So to make a class property to be Promoted you have to provide a visibility modifier (public, private, protected) in front of it like so:

You can use also use the readonly modifier in PHP 8.1 to make the property promoted as shown:

Omitting the visibility modifier make the property unpromoted, therefore you have to initialize it the old way:

Mixing Promoted and Non Promoted Properties

You can mix the Constructor Promoted and Non-Promoted properties in a single constructor:

As you see the $price property is a non-promoted property.

Not Allowed Duplicated Properties

You can’t declare a standard property and promoted property with the same name as this results in a fatal error:

You can remove type hints from properties

Type hints or typed properties isn’t required when using promoted properties although it’s better to type hint properties but it’s not a requirement as in this example: 

Allowed in Traits

As PHP traits can contain constructors, methods and properties, so you can use Constructor Property Constructor as well:

Promoted Properties in Interfaces & Abstract Classes

Interfaces not support promoted properties, any attempt to use them it will trigger a fatal error:

In abstract classes promoted properties supported only if the constructor not marked as abstract:

If the abstract class constructor marked as abstract then promoted properties not allowed:

What's your reaction?

The covariance and contra-variance between objects in php, building a simple application using nuxt 3 vue framework, you may also like, laravel livewire using wire:model on custom component and x-modelable, laravel breeze inertia creating custom pagination component, building a simple datatable with laravel livewire3.

I just could not leave your web site before suggesting that I really enjoyed the standard information a person supply to your visitors? Is gonna be again steadily in order to check up on new posts.

Recent Articles

Lost your password?

  • Backend Development
  • Frontend Development
  • News & Events

Latest Posts

Manipulating headers in the javascript fetch api, the confoo 2024 conference edition is coming, popular tags.

InfoQ Software Architects' Newsletter

A monthly overview of things you need to know as an architect or aspiring architects.

View an example

We protect your privacy.

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

  • English edition
  • Chinese edition
  • Japanese edition
  • French edition

Back to login

Login with:

Don't have an infoq account, helpful links.

  • About InfoQ
  • InfoQ Editors
  • Write for InfoQ
  • About C4Media

Choose your language

php 8 constructor assignment

Discover new ideas and insights from senior practitioners driving change in software. Attend in-person.

php 8 constructor assignment

Discover transformative insights to level up your software development decisions. Register now with early bird tickets.

php 8 constructor assignment

Get practical advice from senior developers to navigate your current dev challenges. Register now with early bird tickets.

php 8 constructor assignment

Level up your software skills by uncovering the emerging trends you should focus on. Register now.

InfoQ Homepage Articles PHP 8 - Classes and Enums

PHP 8 - Classes and Enums

Nov 28, 2022 26 min read

Deepak Vohra

reviewed by

Sergio De Simone

InfoQ Articles Contest

Key takeaways.

  • PHP 8.1 adds support for read-only properties that make class properties invariant and unmodifiable.
  • PHP 8.0 has a new feature that automatically promotes class constructor parameters to corresponding class properties with the same name if the constructor parameters are declared with a visibility modifier and are not of type callable .
  • PHP 8.1 adds support for final class and interface constants, and for interface constants that can be overridden. 
  • As of PHP 8.0, the special ::class constant can be used on objects, and as of PHP 8.1 objects can be used in define() .
  • PHP 8.1 adds support for enumerations, or enums for short, to declare an enumerated set of values that are similar to, though not the same as, class objects.  

Related Sponsored Content

In this article, we will review new PHP 8 features related to classes, including:

  • Enums ,  a layer over classes to specify an enumerated list of possible values for a type 
  • The new readonly modifier for a class property, which makes the property unmodifiable after its initialization 
  • Constructor parameter promotion, useful to assign a constructor parameter value to an object property automatically.

Read-Only Class Properties

Developers have been scrounging for ways to make class properties immutable for use cases such as value objects. Often, properties must be initialized once, usually in a constructor, and are not meant to be ever modified. One alternative that has been used is to make a property private and declare only a public getter method for it. This reduces the scope for modification but does not preclude modification. To make a class property invariant, PHP 8.1 adds support for readonly properties with the condition that the property must be typed. A typed property can indeed be declared readonly with the new readonly keyword. The following script declares a readonly property of type int called $a . The property’s value is set only once in the constructor. The script outputs the value 1 when run. 

To demonstrate the effect of making the property readonly, modify its value with the following assignment.

This will generate a error message:

To demonstrate that the condition that the readonly property must be typed holds, try making an untyped property readonly as in the following script:

The script generates an error message:  

If you don’t want a  readonly property to have a specific type, you can declare it as mixed, e.g.:

In addition to the type requirement, other limitations apply to readonly properties. A readonly property cannot be declared static . Run the following script to demonstrate it:

The script generates an error message:

A readonly property can only be initialized only from the scope in which it is declared. The following script initializes a readonly property, but not in the scope in which it is declared:  

The script generates an error message when run:

You may consider declaring a readonly property with a default value at the time of initialization, but this wouldn’t be particularly useful as you could use a class constant instead. Therefore, setting a default value for a readonly property has been disallowed. The following script declares a default value for a readonly property.

The objective of the readonly property feature is to make a class property immutable. Therefore, a readonly property cannot be unset with unset() after initialization. The following script calls unset() on a readonly property after it has been initialized.

You could always call unset() on a readonly property before initialization as in the following script:

The script runs with no errors and outputs the value of 1 . 

A readonly property cannot be modified by simple reassignment or by any other operator manipulation. The following script does not use a reassignment statement for a readonly property, but uses an increment operator on it. 

The effect is the same, and so is the error message:

Specifically, it is just the readonly property that is immutable, not any objects or resources stored in it. You may modify any objects, and non-readonly properties stored in a readonly property. The following script sets the value of class property $a that is not readonly through a readonly property $obj of type object . 

The script runs with no errors and outputs the value of 1. 

PHP 8.2 adds readonly classes as an extension  of the readonly class properties feature. If a class is declared with the readonly modifier, all class properties are implicitly readonly. The class properties in a readonly class must be typed and non-static, for example:

Readonly classes do have some limitations in that dynamic properties cannot be defined, and only a readonly class can extend another readonly class. 

Constructor property promotion

The objective of constructor property promotion, a feature introduced in PHP 8.0, is to make class property declarations and initializations unnecessary. To elaborate, consider the following script in which class properties $pt1, $pt2, $pt3 , and $pt4 are declared in the Rectangle class and initialized in the class constructor. 

With the new constructor property promotion feature the script is reduced to the following:

The constructor body may be empty or may contain other statements, which are run after the promotion of constructor arguments to the corresponding class properties. The only requirement for a constructor argument to be promoted to a class property is that it include a visibility modifier. The constructor’s argument value is automatically assigned to a class property with the same name. 

The following script snippet demonstrates the automatic promotion and initialization of public constructor arguments to class properties using the example of the Rectangle class with a call to the class constructor as follows: 

You’ll find that the class properties do get added and initialized implicitly, giving the following output.

If a constructor argument does not include a visibility modifier, it is not promoted to the corresponding class property.  Not all constructor arguments have to be promoted. The following script does not promote constructor argument $pt4 as it is not declared with a visibility modifier.

Call the Rectangle class constructor and output class property values, as before. In this case, the result is different because $pt4 does not include a visibility modifier and therefore it is never promoted to a corresponding class property. A warning message is output:

You would need to declare and initialize the $pt4 class property explicitly as in the modified script:

Now, you can call the constructor and output class properties as before with the same output.  

Another requirement for a class constructor argument to be promoted to a corresponding class property is that it is not of type callable.  The following script declares constructor arguments of type callable.

When run the script generates an error message:

In the first article in the PHP 8 series, we explained how to use the new operator in initializers, including for initializing default values for function parameters. The new operator may also be used to set constructor parameter default values, along with constructor property promotion, as in the following script.

The Rectangle class constructor may be called without any constructor arguments, and the promoted property values be output:

The output is:

Objects use in define()

The built-in define() function is used to define named constants. With PHP 8.1 objects can be passed to define() as in the following example script.  

The output from the script is:

Class constants may be declared final

PHP 8.1 allows you to declare class constants using the final keyword.  Additionally, if a class constant is declared final in a class, any class extending it cannot override, or redefine, the constant’s value.   In the following script, a class constant c, which is declared to be final in class A, is redefined in a class B that extends it.

When the script is run, the following error message is generated:

The special ::class constant can be used on objects

The special : :class constant, which allows for fully qualified class name resolution at compile time, can also be used with class objects as of PHP 8.0. One difference is that class name resolution happens at runtime with objects, unlike compile-time resolution for classes. Using : :class on an object is equivalent to calling  get_class() on the object.  The following script uses ::class on an object of class A, which output “A”. 

Interfaces constants can be overridden

As of PHP 8.1, interface constants can be overridden by a class, or interface, that inherits them. In the following script, interface constant c is overridden by a class constant with the same name. The value of the overridden constant may be the same or  different. 

Both constant values may be output:

As it holds for class constants that are declared final , interface constants declared final cannot be overridden. The following script overrides an interface constant declared final .

An error message is output when script is run:

Autoload function __autoload() is removed

The __autoload() function that was deprecated in PHP 7.2.0 has been removed in PHP 8.0. If the _ _autoload() function is called, the following error message results:

An enumeration, or enum for short, is a new feature to declare a custom type with an explicit set of possible values. The new language construct enum is used to declare an enumeration with the simplest enumeration being an empty one.

An enum may declare possible values using the case keyword, for example:

The discussion on enumerations is bundled with classes because of their similarity.

How enums are similar to classes

  • An enum is a class. The example enum SortType is a class, and its possible values are object instances of the class.
  • Enums share the same namespace as classes, interfaces, and traits.
  • Enums are autoloadable as classes are.
  • Each enum value, such as the Asc, Desc and Shuffle values for the SortType enum is an object instance. An enum value would pass an object type check.
  • An enum’s values, or the case names, are internally represented as class constants, and are therefore case-sensitive.

Enums are useful for several use cases, such as:

  • A structured alternative to a set of constants 
  • Custom type definitions
  • Data modeling
  • Monad-style programming
  • Defining a domain model
  • Validation by making unsupported values unrepresentable, resulting in reduced requirement for code testing 

We shall discuss enums with some examples. Because an enum’s values are objects they may be used where an object can be used, including as function parameter type, and function return type. In the following script, enum SortType is used as a function parameter type, and function return type.

The output from the script is :

Next, we shall use the same example of sorting an array that  we used in the first article in this series. The parameter for the sortArray function is of type SortType , which is an enum. 

The enum object value is compared using the == operator.

The same example as used with enums is as follows:

The output of the script  for the array sorting example is:

Because an enum case, or possible value, is an object instance, the instanceof operator may be used with an enum value, for example:

An enum’s value is not converted to a string and cannot be used as an equivalent string. For example, if you call the sortArray() function with a string argument:

An error would result:

All enum values, or cases, have a read-only property called name that has its value as the case-sensitive name of the case. The name property could be used for debugging. For example, the following print statement would output “Asc”. 

An enum’s values must be unique, case-sensitive values. The following script has unique values:

But the following script doesn’t declare unique values:

The script generates the following error message:

The enumerations we discussed are basic enumerations, or pure enums. A pure enum only defines pure cases with no related data. Next, we discuss another type of enums called backed enums.

Backed enums

A backed enum defines scalar equivalents of type string or int for the enum cases, for example: 

The scalar equivalent can be of type int or string , but not a union of int|string , and all cases of a backed enum must declare a scalar value. To demonstrate use the following Backed Enum:

It would produce an error message:

The scalar equivalents for backed enum cases must be unique. To demonstrate, use the following script that declares the same scalar equivalent for two enum cases:

The script would result in an error message:

The scalar equivalents may be literal expressions in addition to being literal values, as example:

All backed enum values, or backed cases, have an additional read-only property called value that has its value as the scalar value of the backed case. For example, the following print statement would output the scalar equivalent value for the Desc case:

Here, value is a read-only property and unmodifiable. The following snippet assigns a variable as a reference to the value property of a backed case:

The variable assignment would generate an error message:

Backed enums implement an internal interface BackedEnum that declares two methods:

  • from(int|string): self – Takes a scalar enum value for a backed case and returns the corresponding enum case. Returns a ValueError if the scalar value is not found.
  • tryFrom(int|string): ?self – Takes a scalar enum value for a backed case and returns the corresponding enum case. Returns null if the scalar value is not found.

The following script demonstrates the use of these methods.

The from() and tryFrom() methods use strict/weak typing modes, the default being weak typing, which implies some implicit conversion. Float and string values for integers get converted to integer values as demonstrated by the following script:

A string that cannot get converted to an integer must not be passed when an int is expected, as in:

The preceding would result in a  error message:

In strict typing mode, the type conversion is not applied, and error messages such as the preceding, or the following are generated:

Both pure and backed enums implement an internal interface called UniEnum that provides a static method called cases() that outputs the possible values for the enum, i.e., the enum cases. The following script demonstrates the cases() method.

Enums may include methods and implement an interface

Enums, both pure and backed, may declare methods, similar to class instance methods. Enums may also implement an interface. The enum must implement the interface functions in addition to any other functions. The following script is a variation of the same array sorting example that includes an enum that implements an interface. The enum implements a function  from the interface in addition to a function not belonging to the interface. 

The output from the script is as follows:

A backed enum may also implement an interface and provide additional methods as in the following script:

The output is as follows:

Enums may declare static methods 

An enum may declare static methods. In a variation of the array sorting example, a static method chooseSortType() is used to choose the sort type based on the length of the array to be sorted:

Enums may declare constants

An enum may declare constants. The following script declares a constant called A. 

The constants may refer to enum’s own cases, which are also constants. The following script for sorting an array demonstrates the use of constants that refer to the enum in which they are declared.

Because an enum’s values are constants themselves, an explicit constant may not redefine an enum’s value. We demonstrate this in the following script:

A enum’s case value must be compile-time evaluable, as  the following script declaring an enum case as a constant demonstrates.

An error message is generated:

Enums with traits

Enums may use traits. The following script for sorting an array declares a trait called ChooseSortType and uses the trait in an enum.

How are enums different from classes

While we mentioned that enums are similar to classes, they are different in many regards:

  • Enums are serialized differently from objects
  • Enums don’t have a state, which a class object does
  • Enums don’t declare constructors as no object initialization is needed
  • Enums can’t extend other enums; that is, no inheritance
  • Object and static properties are not supported
  • Enums can’t be instantiated with the new operator
  • The print_r output is different as compared to class objects

To demonstrate one of these differences, consider the following script in which an enum declares a class property:

The script generates error message:

To demonstrate another of these differences, consider the following script in which an enum is instantiated:

To demonstrate another difference, the print_r output for a pure enum, and a backed enum is listed by script:

The output is :

Enums may nor declare a __toString method. To demonstrate use the following script in which an enum implements the Stringable interface and provides implementation for the __toString method. 

In this article we discussed most of the class-related features in PHP 8, including enums, the new readonly modifier for class properties, and constructor parameter promotion.

In the next article in the series we will explore functions and methods related new features. …  

About the Author

Rate this article, this content is in the programming languages topic, related topics:.

  • Development
  • Programming Languages
  • System Programming
  • PHP 8.x Article Series

Related Editorial

Popular across infoq, will c++ become a safe language like rust and others, infoq software architecture and design trends report - april 2024, infoq architecture and design trends in 2024, qcon london: meta used monolithic architecture to ship threads in only five months, architecture does not emerge - a conversation with tracy bannon, microsoft azure introduces retina: a cloud native container networking observability platform, related content, the infoq newsletter.

A round-up of last week’s content on InfoQ sent out every Tuesday. Join a community of over 250,000 senior developers. View an example

php 8 constructor assignment

PHP RFC: Constructor Property Promotion

  • Date: 2020-03-26
  • Author: Nikita Popov nikic@php.net
  • Status: Implemented
  • Target Version: PHP 8.0
  • Implementation: https://github.com/php/php-src/pull/5291
  • Introduction

Currently, the definition of simple value objects requires a lot of boilerplate, because all properties need to be repeated at least four times. Consider the following simple class:

The properties are repeated 1) in the property declaration, 2) the constructor parameters, and 3) two times in the property assignment. Additionally, the property type is repeated twice.

Especially for value objects, which commonly do not contain anything more than property declarations and a constructor, this results in a lot of boilerplate, and makes changes more complicated and error prone.

This RFC proposes to introduce a short hand syntax, which allows combining the definition of properties and the constructor:

This short-hand code is strictly equivalent to the previous example, but more concise. The choice of syntax is adopted from our sister language Hack .

When a method parameter is prefixed with one of the visibility keywords public , protected or private , it is considered to be “promoted”. For each promoted parameter, a property with the same name will be added, and a forwarding assignment to that property included in the body of the constructor, according to the detailed rules outlined in the following.

  • Constraints

Promoted parameters may only occur inside non-abstract constructors. As such, all of the following are illegal:

While unusual, promoted parameters may occur inside trait constructors.

Promoted properties have to be prefixed by one of the visibility keywords, use of var is not supported:

Properties declared through promoted parameters are subject to the same restrictions as normal property declarations. In particular, it is not possible to declare the same property twice:

It is also not possible to use the callable type, because it is not supported as a property type:

Similarly, because promoted parameters imply a property declaration, nullability must be explicitly declared, and is not inferred from a null default value:

Variadic parameters cannot be promoted:

The reason is that in this case the type of the individual arguments (here: string), and the type of the variadic parameter into which they are collected (here: array of string) differ. While we could implicitly give the $strings property an array type for variadic parameters, this makes the transform less transparent.

Explicit property declarations and properties promoted from constructor arguments may be combined. A constructor may also have both promoted and non-promoted parameters.

Promoted properties follow a simple desugaring, where the following transformation is applied for all promoted parameters:

The visibility and type of the automatically declared property match that of the promoted parameter. Notably, the property is declared without a default value (i.e. it starts out in an uninitialized state), and the default value is only specified on the constructor parameter.

While repeating the default value on the property declaration would currently appear harmless, there are forward-compatibility reasons why it is preferable to only specify the default once.

The first is a possible future extension to allow arbitrary expressions in parameter and property defaults:

In this case, if the default value were duplicated to the property declaration, we would end up constructing the optional Dependency object twice, which is undesirable and violates the single-evaluation rule.

Additionally, under the rules of the recent readonly property proposal the assignment in the constructor would not be legal if the property declared a default value.

If the promoted parameter is passed by reference, then the forwarding assignment is also performed by reference:

The forwarding property assignments occur at the start of the constructor. As such, it is possible to access both the parameter and the property in the constructor, for example to enforce additional validation:

Reflection (and other introspection mechanisms) will observe the state after desugaring. This means that promoted properties will appear the same way as explicitly declared properties, and promoted constructor arguments will appear as ordinary constructor arguments.

While PHP does not expose doc comments on parameters, doc comments on promoted properties will be retained:

As the example indicates, this allows using doc comment based annotations with promoted properties.

Additionally, two new methods are added:

  • ReflectionProperty::isPromoted() returns true for properties that have been implicitly generated as part of constructor promotion.
  • ReflectionParameter::isPromoted() returns true for parameters that have resulted in the generation of an implicit property as part of constructor promotion.

Most reflection code should not care whether properties are generated or not, but this information will allow reconstructing the structure or the original code more easily.

  • Inheritance

Constructor promotion can be used in conjunction with inheritance, but has no special interaction with it beyond what is implied by the desugaring. A typical use-case involving inheritance is shown in the following, based on an abstract syntax tree representation:

The ParamNode class declares a number of promoted properties (those prefixed with public ) and additionally takes two normal parameters (those not prefixed with public ), which are simply forwarded to the parent constructor. The code is equivalent to the following desugaring:

It should be noted that the property assignments happen before the parent constructor is invoked. This is unusual in terms of coding style, but should not impact behavior for non-degenerate cases.

As PHP 8 also introduces attributes , we need to consider how these features interact. Attributes are allowed both on properties and on parameters.

This code could desugar in one of four ways:

  • The attribute is applied only to the parameter.
  • The attribute is applied only to the implied property.
  • The attribute is applied both to the parameter and the property.
  • Attributes on promoted properties are forbidden, due to ambiguity.

Here are the possible transformations:

This RFC proposes to use option 3 (applying the attribute to both property and parameter), as it is the most flexible. The isPromoted() Reflection APIs can be used by attribute validation code to discard the property or parameter attribute, if necessary.

However, I consider this to be something of an implementation detail. If further work on attributes prior to the PHP 8 release shows that it would be advantageous to place the attribute only on the property, we should be open to such a change.

  • Coding Style Considerations

This section gives non-normative coding style recommendations.

If constructor property promotion is used, it is recommended that the constructor be placed as the first method in the class, and directly following any explicit property declarations. This ensures that all declared properties are grouped together and visible at a glance. Coding standards that currently require static methods to be placed first should be adjusted to place the class constructor first.

If @param annotations on promoted properties are used, these annotations should also be treated as @var annotations by PHP documentation tooling:

Finally, it should be noted that constructor property promotion is just a convenient short-hand notation that covers the most common cases. A promoted property can always be converted into an explicit property with custom initialization logic at a later point in time. Such a change does not constitute a backwards-compatibility break.

  • Backward Incompatible Changes
  • Future Scope

Larry provided some broader vision on how this feature can be combined with other features to improve our object initialization story in https://hive.blog/php/@crell/improving-php-s-object-ergonomics .

This feature, or something very similar, is already supported by a number of other languages.

  • Kotlin (primary constructors serve a similar purpose)

There have also been three previous RFCs on related topics:

  • Automatic property initialization : This introduces a weaker form of promotion that still requires separate property declarations, but saves the assignment boilerplate.
  • Constructor Argument Promotion : This is pretty much the same as this RFC ...
  • Code free constructor : This pursues the Kotlin approach instead.

Voting started 2020-05-15 and closes 2020-05-29.

  • Show pagesource
  • Old revisions
  • Back to top

php 8 constructor assignment

Table of Contents

ASolutions

Magento | Magento 2 | PHP

Php 8.0 constructor property promotion.

Constructor Property Promotion

Hello Everyone, Welcome to my blog post . Today, I would like to discuss about the constructor property promotion. 

What is Constructor Property Promotion

PHP has recently launched its new version i.e. PHP 8 and it consists of many new features. Constructor property promotion is one of the new features introduced in PHP 8. In previous versions of PHP(~7.*), we used to define our variables as class property and assign its value in the constructor. Please check out the following example for reference:

In the above example, we can see the $x, $y & $z is defined as class property and we have assigned a value in the constructor, and it requires a lot of boilerplate because all properties need to be repeated at least four times.

The properties are repeated 

1) in the property declaration.

2) the constructor parameters.

3) two times in the property assignment. Additionally, the property type is repeated twice.

To avoid this repetitive assignment PHP 8 came up with a new solution in the new version. Please check out the following example for reference.

Here, we can use the shorthand syntax which allows combining the definition of properties and the constructor. In the constructor, we are assigning variable values with access specifiers. 

When we prefix variable with one of the access specifiers like private, public, and protected it is considered as “promoted”. For every promoted parameter, a property with the same name will be added for example.

A variable is assigned with $x, this shorthand syntax is inherited from the sister site of PHP Hack

Please let me know your thought about this blog in the comment section below. Or, you can write me an email on my email id i.e. [email protected] . Till next time happy coding :). 

[post-views]

Related Posts

Seller Assisted Shopping

Seller Assisted Shopping

Maximizing Your Magento 2 Application with the Flexibility of Interceptors

Maximizing Magento 2 Application with the Flexibility of Interceptors

Null Coalescing Operator

Null Coalescing Operator

3 thoughts on “ php 8.0 constructor property promotion ”.

I went through your blog, it is really nice and informative. Keep sharing more such content!!!

Say, you got a nice post. Thanks Again. Really Great. Allen Maletz

Im thankful for the post. Really looking forward to read more. Really Great. Lou Gaznes

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Save my name, email, and website in this browser for the next time I comment.

  • Language Reference
  • Classes and Objects

Basic class definitions begin with the keyword class , followed by a class name, followed by a pair of curly braces which enclose the definitions of the properties and methods belonging to the class.

The class name can be any valid label, provided it is not a PHP reserved word . A valid class name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$ .

A class may contain its own constants , variables (called "properties"), and functions (called "methods").

Example #1 Simple Class definition

The pseudo-variable $this is available when a method is called from within an object context. $this is the value of the calling object.

Calling a non-static method statically throws an Error . Prior to PHP 8.0.0, this would generate a deprecation notice, and $this would be undefined.

Example #2 Some examples of the $this pseudo-variable

Output of the above example in PHP 7:

Output of the above example in PHP 8:

Readonly classes

As of PHP 8.2.0, a class can be marked with the readonly modifier. Marking a class as readonly will add the readonly modifier to every declared property, and prevent the creation of dynamic properties . Moreover, it is impossible to add support for them by using the AllowDynamicProperties attribute. Attempting to do so will trigger a compile-time error.

As neither untyped nor static properties can be marked with the readonly modifier, readonly classes cannot declare them either:

A readonly class can be extended if, and only if, the child class is also a readonly class.

To create an instance of a class, the new keyword must be used. An object will always be created unless the object has a constructor defined that throws an exception on error. Classes should be defined before instantiation (and in some cases this is a requirement).

If a variable containing a string with the name of a class is used with new , a new instance of that class will be created. If the class is in a namespace, its fully qualified name must be used when doing this.

Note : If there are no arguments to be passed to the class's constructor, parentheses after the class name may be omitted.

Example #3 Creating an instance

As of PHP 8.0.0, using new with arbitrary expressions is supported. This allows more complex instantiation if the expression produces a string . The expressions must be wrapped in parentheses.

Example #4 Creating an instance using an arbitrary expression

In the given example we show multiple examples of valid arbitrary expressions that produce a class name. This shows a call to a function, string concatenation, and the ::class constant.

In the class context, it is possible to create a new object by new self and new parent .

When assigning an already created instance of a class to a new variable, the new variable will access the same instance as the object that was assigned. This behaviour is the same when passing instances to a function. A copy of an already created object can be made by cloning it.

Example #5 Object Assignment

The above example will output:

It's possible to create instances of an object in a couple of ways:

Example #6 Creating new objects

It is possible to access a member of a newly created object in a single expression:

Example #7 Access member of newly created object

The above example will output something similar to:

Note : Prior to PHP 7.1, the arguments are not evaluated if there is no constructor function defined.

Properties and methods

Class properties and methods live in separate "namespaces", so it is possible to have a property and a method with the same name. Referring to both a property and a method has the same notation, and whether a property will be accessed or a method will be called, solely depends on the context, i.e. whether the usage is a variable access or a function call.

Example #8 Property access vs. method call

That means that calling an anonymous function which has been assigned to a property is not directly possible. Instead the property has to be assigned to a variable first, for instance. It is possible to call such a property directly by enclosing it in parentheses.

Example #9 Calling an anonymous function stored in a property

A class can inherit the constants, methods, and properties of another class by using the keyword extends in the class declaration. It is not possible to extend multiple classes; a class can only inherit from one base class.

The inherited constants, methods, and properties can be overridden by redeclaring them with the same name defined in the parent class. However, if the parent class has defined a method or constant as final , they may not be overridden. It is possible to access the overridden methods or static properties by referencing them with parent:: .

Note : As of PHP 8.1.0, constants may be declared as final.

Example #10 Simple Class Inheritance

Signature compatibility rules

When overriding a method, its signature must be compatible with the parent method. Otherwise, a fatal error is emitted, or, prior to PHP 8.0.0, an E_WARNING level error is generated. A signature is compatible if it respects the variance rules, makes a mandatory parameter optional, adds only optional new parameters and doesn't restrict but only relaxes the visibility. This is known as the Liskov Substitution Principle, or LSP for short. The constructor , and private methods are exempt from these signature compatibility rules, and thus won't emit a fatal error in case of a signature mismatch.

Example #11 Compatible child methods

The following examples demonstrate that a child method which removes a parameter, or makes an optional parameter mandatory, is not compatible with the parent method.

Example #12 Fatal error when a child method removes a parameter

Output of the above example in PHP 8 is similar to:

Example #13 Fatal error when a child method makes an optional parameter mandatory

Renaming a method's parameter in a child class is not a signature incompatibility. However, this is discouraged as it will result in a runtime Error if named arguments are used.

Example #14 Error when using named arguments and parameters were renamed in a child class

The class keyword is also used for class name resolution. To obtain the fully qualified name of a class ClassName use ClassName::class . This is particularly useful with namespaced classes.

Example #15 Class name resolution

Note : The class name resolution using ::class is a compile time transformation. That means at the time the class name string is created no autoloading has happened yet. As a consequence, class names are expanded even if the class does not exist. No error is issued in that case. Example #16 Missing class name resolution <?php print Does\Not\Exist ::class; ?> The above example will output: Does\Not\Exist

As of PHP 8.0.0, ::class may also be used on objects. This resolution happens at runtime, not compile time. Its effect is the same as calling get_class() on the object.

Example #17 Object name resolution

Nullsafe methods and properties

As of PHP 8.0.0, properties and methods may also be accessed with the "nullsafe" operator instead: ?-> . The nullsafe operator works the same as property or method access as above, except that if the object being dereferenced is null then null will be returned rather than an exception thrown. If the dereference is part of a chain, the rest of the chain is skipped.

The effect is similar to wrapping each access in an is_null() check first, but more compact.

Example #18 Nullsafe Operator

Note : The nullsafe operator is best used when null is considered a valid and expected possible value for a property or method return. For indicating an error, a thrown exception is preferable.

User Contributed Notes 12 notes

To Top

COMMENTS

  1. PHP 8: Constructor property promotion

    PHP 8: Constructor property promotion. Personally, I use value objects and data transfer objects all the time in my projects. I even wrote a dedicated post on how to treat data in our code a while back. Naturally, I'm very happy with the constructor property promotion RFC, it's passed and will be added in PHP 8. You see, this feature reduces a ...

  2. PHP: Constructors and Destructors

    Constructor Promotion. As of PHP 8.0.0, constructor parameters may also be promoted to correspond to an object property. It is very common for constructor parameters to be assigned to a property in the constructor but otherwise not operated upon. ... As of PHP 8.1.0, objects can be used as default parameter values, static variables, and global ...

  3. Class constructor property promotion

    Constructor Property Promotion is a new syntax in PHP 8 that allows class property declaration and constructor assignment right from the constructor. A typical class that declares a property, and then assigns a value to it in the class constructor is quite verbose.

  4. Constructor Property Promotion in PHP 8

    Constructor Property Promotion is a new syntax provided in the newer version of PHP 8 that allows class property declaration and constructor assignment, variable assignment right from the constructor without getting in the condition of boilerplate code. This avoids having to type the class property name and property type from many to just once.

  5. Constructor Property Promotion in PHP 8.0

    Since PHP 8.0, we can use constructor property promotion. This is a new syntax that allows to combine properties declaration, constructor parameters and properties assignments in one place. We can rewrite the previous code as follows: 1. 2.

  6. Constructor property promotion in PHP 8

    Constructor property promotion in PHP 8. 23 juil. 2022 • 3 min read. This post is free for all to read thanks to the investment Mindsers Club members have made in our independent publication. If this work is meaningful to you, I invite you to join the club today. If there is one redundant and boring thing in object-oriented programming, it is ...

  7. PHP 8: Constructor property promotion

    It seems just repetitive work with no real benefits. Thankfully, starting PHP 8.0, when a visibility modifier is included in a constructor argument, PHP treats it as both an object property and a constructor argument, and assigns the argument value to the property. So you can now write this in PHP 8:

  8. Constructor Property Promotion in PHP 8

    Constructor property promotion is a new PHP 8 convenience feature which helps you minimise code repetition. It lets you combine the definition and initialisation of properties into a single constructor statement. A Traditional Class Constructor property promotion (CPP from hereon) is most useful in the context of value objects. ...

  9. PHP 8: Constructor Property Promotion

    Constructor property promotion is a feature introduced in PHP 8 that allows values passed to a constructor to be automatically set as class properties without the need to write the assignment statement in the body of the constructor. For a better understanding of the concept, let's take a look at the way values were assigned to class properties ...

  10. PHP 8.0 Constructor Property Promotion

    Perhaps the largest quality-of-life improvement to PHP 8.0 is Constructor Property Promotion. The syntax has been borrowed largely from Hack, Facebook's PHP fork, although it exists in other languages like TypeScript and Kotlin with various syntaxes. It's easiest to explain with an example. Consider your typical service class in a modern ...

  11. Constructors and Destructors

    Constructor Promotion. As of PHP 8.0.0, constructor parameters may also be promoted to correspond to an object property. It is very common for constructor parameters to be assigned to a property in the constructor but otherwise not operated upon. ... As of PHP 8.1.0, objects can be used as default parameter values, static variables, and global ...

  12. Constructor property promotion in PHP 8

    If none of the properties are promoted, that doesn't necessarily mean that all properties of that constructor are special cases. Maybe the developer who wrote the code doesn't yet know that the promoted properties exist, maybe he doesn't want to use this feature, or maybe his code was written before the arrival of PHP 8. Anyway, you get the idea.

  13. PHP 8 Constructor Property Promotion: Simplifying Class Definitions

    PHP 8's Constructor Property Promotion functionality helps developers simplify their code by reducing the amount of boilerplate required to define and initialize class properties. This feature makes PHP classes more readable and maintainable, encouraging better coding practices and improving developer productivity. PHP.

  14. Constructor Property Promotion in PHP 8

    In the property declaration. In the constructor parameters. In the property assignment in the costructor body. So, a class with properties declared would look like so. Things are getting interesting in PHP 8 for this scenario. According to this RFC (which is accepted), Constructor Property Promotion is coming in PHP 8.

  15. PHP 8 constructor promotion with inheritance (subclasses)

    PHP 8 has this amazing feature called "constructor promotion" that allows you to define the properties of a class and set them in one go via the constructor. This removes a lot of boilerplate. However, how do we create a subclass which defines additional properties? Here we have the base class that we want to extend:

  16. Constructor Property Promotion In PHP 8.0

    Typically when a constructor argument includes a modifier such as public, private, protected, etc, PHP interpreter will interpret it as an object property and a constructor argument, then assign the argument value to the property. Note that this feature from PHP 8.0 and later so you can't use it in PHP < PHP 8.0 . Promoted Property & Modifiers

  17. PHP 8

    As of PHP 8.0, the special ::class constant can be used on objects, and as of PHP 8.1 objects can be used in define(). PHP 8.1 adds support for enumerations, or enums for short, to declare an ...

  18. PHP: rfc:constructor_promotion

    When a method parameter is prefixed with one of the visibility keywords public, protected or private, it is considered to be "promoted".For each promoted parameter, a property with the same name will be added, and a forwarding assignment to that property included in the body of the constructor, according to the detailed rules outlined in the following.

  19. php 8

    @NigelRen In case you're not aware, #[...] is the syntax introduced in PHP 8.0 for attributes AKA annotations. It's highlighted as a comment here, and will be treated as one by earlier versions of PHP (which is one of the reasons that syntax was eventually chosen), but it is indeed a reference to the MyAttribute class constructor. The question is a reasonable one, and Kazz's answer explains ...

  20. PHP 8.0 Constructor Property Promotion

    PHP has recently launched its new version i.e. PHP 8 and it consists of many new features. Constructor property promotion is one of the new features introduced in PHP 8. In previous versions of PHP (~7.*), we used to define our variables as class property and assign its value in the constructor. Please check out the following example for reference:

  21. PHP: The Basics

    class. Basic class definitions begin with the keyword class, followed by a class name, followed by a pair of curly braces which enclose the definitions of the properties and methods belonging to the class.. The class name can be any valid label, provided it is not a PHP reserved word.A valid class name starts with a letter or underscore, followed by any number of letters, numbers, or underscores.

  22. Best way to do multiple constructors in PHP

    Here is an elegant way to do it. Create trait that will enable multiple constructors given the number of parameters. You would simply add the number of parameters to the function name "__construct". So one parameter will be "__construct1", two "__construct2"... etc. trait constructable.

  23. php

    Rather than creating the token in your constructor, you could take advantage of Laravel's model events. In short, this allows you to listen for an event (e.g. "created," "updated," etc.), and perform an action on that event. If you replace your constructor with the following, it should solve the issue: