PHP class syntax basics
In chapter 1 we read through the Order class without explaining its contents in detail.
This chapter works through class syntax like private and public function, one piece at a time.
Classes and properties
You define a class with the class keyword.
Variables written inside a class are called properties.
class Order
{
private array $items = [];
private string $customerEmail;
}
private array $items = []; declares a property named $items.
array is a type declaration: assigning anything other than an array to this property is an error.
private is a visibility modifier, explained below.
Methods
A function defined inside a class is called a method.
Inside a method you can use the special variable $this to reach the object's own properties and methods.
class Order
{
private array $items = [];
public function addItem(string $name, int $price): void
{
$this->items[] = ['name' => $name, 'price' => $price];
}
}
$this->items refers to the $items property held by this object itself.
Visibility modifiers: public, protected, and private
Properties and methods carry a visibility modifier that decides how far outside the class they can be reached.
- public: reachable from anywhere
- protected: reachable from the class itself and from classes that inherit from it (inheritance is covered in chapter 5)
- private: reachable only from inside the class itself
class Order
{
private array $items = [];
public function getItemCount(): int
{
return count($this->items);
}
}
$order = new Order();
$order->getItemCount(); // OK: a public method, so it can be called
$order->items; // Error: a private property, so it cannot be reached from outside the class
Making $items private prevents it from being rewritten directly from outside the class.
Chapter 3, "Encapsulation and information hiding," covers this idea in detail.
Constructors
The method called automatically when an object is created (when you new it) is called the constructor.
In PHP you define it under the name __construct.
class Order
{
private string $customerEmail;
public function __construct(string $customerEmail)
{
$this->customerEmail = $customerEmail;
}
}
$order = new Order('taro@example.com');
Writing new Order('taro@example.com') calls the constructor, and the argument $customerEmail is assigned to $this->customerEmail.
Constructor promotion
A very common thing to write in a constructor is to take an argument and assign it straight to a property of the same name.
The constructor of the Order class above has exactly this shape.
PHP 8.0 introduced constructor promotion, which lets you leave out this boilerplate1.
class Order
{
private string $customerEmail;
public function __construct(string $customerEmail)
{
$this->customerEmail = $customerEmail;
}
}
class Order
{
public function __construct(
private string $customerEmail,
) {
}
}
When you put a visibility modifier such as private on a constructor argument, PHP declares a property of the same name for you and does the assignment as well.
What used to be spread across two places — the property declaration and the assignment — comes together in one.
readonly properties
PHP 8.1 introduced readonly properties, whose value cannot be changed once initialized2.
class Order
{
public function __construct(
public readonly string $customerEmail,
) {
}
}
$order = new Order('taro@example.com');
$order->customerEmail = 'jiro@example.com'; // Error: a readonly property cannot be reassigned
For a value that should never change once created, such as a customer's email address, marking it readonly turns "do not rewrite this by accident" into something the PHP language itself enforces.
enum
To represent data that can only take one of a fixed set of options, PHP 8.1 introduced enum3.
enum OrderStatus
{
case Pending;
case Shipped;
case Delivered;
}
$status = OrderStatus::Pending;
When you want to pair each case with a value such as a string or an integer, use a backed enum.
enum OrderStatus: string
{
case Pending = 'pending';
case Shipped = 'shipped';
case Delivered = 'delivered';
}
echo OrderStatus::Pending->value; // 'pending'
The value OrderStatus::Pending states its intent far more clearly than the string 'pending' or the number 1.
Bugs from typos in strings are caught by PHP's type system as well.
Summary
- Variables inside a class are called properties, and functions are called methods
- Visibility modifiers (public, protected, private) control how far outside the class something can be reached
- The constructor (
__construct) is called when an object is created - Constructor promotion (PHP 8.0) is shorthand that brings the property declaration and the assignment into one place
- readonly properties (PHP 8.1) prevent reassignment after initialization
- enum (PHP 8.1) expresses a value that can only take a fixed set of options as a type
What to read next
The next chapter covers encapsulation and information hiding. We look at the danger of public properties and at how to decide whether you need getters and setters.
Exercises
Rewrite the following class using constructor promotion and readonly properties
class Product
{
private string $name;
private int $price;
public function __construct(string $name, int $price)
{
$this->name = $name;
$this->price = $price;
}
public function getName(): string
{
return $this->name;
}
public function getPrice(): int
{
return $this->price;
}
}
Sample answer
class Product
{
public function __construct(
private readonly string $name,
private readonly int $price,
) {
}
public function getName(): string
{
return $this->name;
}
public function getPrice(): int
{
return $this->price;
}
}
Constructor promotion brings the property declaration and the assignment together, and readonly guarantees that $name and $price are not changed after creation.