Constructors and encapsulation
An object should come into existence in a complete, valid state and should not let outside code corrupt its data. The constructor takes care of the first part, access modifiers of the second.
The constructor
The __construct() method is called automatically when an object is created. Arguments go in the parentheses after the class name:
<?php
class Product
{
public string $title;
public float $price;
public function __construct(string $title, float $price)
{
$this->title = $title;
$this->price = $price;
}
}
$product = new Product('Tea', 150);
echo $product->title; // TeaThe short form
You can declare a property and fill it from a parameter in one line — just put the access modifier on the constructor parameter:
<?php
class Product
{
public function __construct(
public string $title,
public float $price,
) {}
}
$product = new Product('Tea', 150);
echo "{$product->title}: {$product->price}"; // Tea: 150This class does the same as the previous one, without the repetition.
private
A private property is accessible only inside the class. It can be changed only through methods, and methods can validate the data:
<?php
class Account
{
private int $balance = 0;
public function deposit(int $amount): void
{
if ($amount <= 0) {
return;
}
$this->balance += $amount;
}
public function balance(): int
{
return $this->balance;
}
}
$account = new Account();
$account->deposit(100);
$account->deposit(-50);
echo $account->balance(); // 100The negative deposit was rejected. Hiding data behind methods is called encapsulation: the object itself makes sure its state stays valid.
Read-only properties
A readonly property can be set once, in the constructor. Trying to change it later throws an error:
<?php
class Point
{
public function __construct(
public readonly int $x,
public readonly int $y,
) {}
}
$point = new Point(2, 3);
echo $point->x; // 2Such properties suit data that must not change after the object is created.
Class constants
A value that is shared by all objects and never changes is declared as a constant. Inside the class you refer to it through self:::
<?php
class Circle
{
public const PI = 3.14159;
public function __construct(private float $radius) {}
public function area(): float
{
return self::PI * $this->radius ** 2;
}
}
echo (new Circle(2))->area(); // 12.56636A common mistake
Making every property public is easier, but then any code can write anything into the object. Start with private and expose only what is really needed outside.