Skip to content

PHP Tutorial Object-Oriented PHP

Constructors

Lesson 202 of 369 2 min read By Deepak Paswan Updated Oct 5, 2026

A constructor is a special method that PHP runs automatically when you create an object with new. It is the place to set up the object so it is valid from the start.

index.php
PHP
<?php
class User
{
    public string $name;
    public string $email;

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

$user = new User("Isha", "isha@example.com");

echo $user->name . " <" . $user->email . ">";
Output
OUTPUT
Isha <isha@example.com>

The method is always called __construct. The arguments you pass to new User(...) go to it.

Why constructors matter

Without a constructor, you could create a User with no name and no email, and nothing would warn you. With one, a User always has a name and an email, because new User() will not work without them.

index.php
PHP
<?php
class User
{
    public function __construct(public string $name) {}
}

try {
    $u = new User();
} catch (ArgumentCountError $e) {
    echo $e->getMessage();
}
Output
OUTPUT
Too few arguments to function User::__construct(), 0 passed in /path/to/index.php on line 8 and exactly 1 expected

Constructor property promotion (PHP 8.0+)

Writing each property three times (declare, parameter, assign) is repetitive. PHP 8 lets you declare and assign in one step by adding a visibility word to the constructor parameter.

index.php
PHP
<?php
class User
{
    public function __construct(
        public string $name,
        public string $email,
        public bool $active = true,
    ) {}
}

$user = new User("Isha", "isha@example.com");

echo $user->name . ", active: " . ($user->active ? "yes" : "no");
Output
OUTPUT
Isha, active: yes

This is the same as the long version above, in four lines. Constructor Property Promotion goes deeper.

Validate in the constructor

If the data is not valid, the object should not exist. Throw an exception.

index.php
PHP
<?php
class Email
{
    public function __construct(public readonly string $value)
    {
        if (filter_var($value, FILTER_VALIDATE_EMAIL) === false) {
            throw new InvalidArgumentException("Invalid email: $value");
        }
    }
}

try {
    new Email("not-an-email");
} catch (InvalidArgumentException $e) {
    echo $e->getMessage();
}
Output
OUTPUT
Invalid email: not-an-email

An Email object, once created, is always a valid email. Code that receives one does not need to check again.

Default values and named arguments

index.php
PHP
<?php
class Connection
{
    public function __construct(
        public string $host = "127.0.0.1",
        public int $port = 3306,
        public string $charset = "utf8mb4",
    ) {}
}

$c = new Connection(port: 3307);

echo "{$c->host}:{$c->port}";
Output
OUTPUT
127.0.0.1:3307

Do not do heavy work

A constructor should set things up quickly. Do not make network calls or read big files there. A constructor that can fail in complicated ways is hard to test.

Static constructors

A static method can give a clearer name to a creation path.

index.php
PHP
<?php
class Money
{
    private function __construct(public readonly int $cents) {}

    public static function fromFloat(float $amount): self
    {
        return new self((int) round($amount * 100));
    }
}

echo Money::fromFloat(19.99)->cents;
Output
OUTPUT
1999

The constructor is private, so the only way to build a Money is through the named methods.

lightbulb
One valid state
The goal of a constructor is: after new, the object is complete and valid. If that is not true, redesign the constructor.