Classes and Objects
Object-oriented programming bundles data and the code that works on it into objects. A class is the blueprint: it declares the properties each object has and the methods it can perform. Every modern PHP framework and library is built from classes, so this is where PHP code starts to look professional.
Defining a class
<?php class Dog { public string $name = ""; public int $age = 0; public function bark(): string { return "{$this->name} says woof!"; } public function birthday(): void { $this->age++; } } $dog = new Dog(); $dog->name = "Biscuit"; $dog->age = 3; echo $dog->bark(), "\n"; $dog->birthday(); echo "{$dog->name} is now {$dog->age}\n";
Biscuit says woof! Biscuit is now 4
class Dog { … }declares the class. Class names are PascalCase.- Properties (
$name,$age) hold each object's data. Give them types and default values. - Methods are functions inside the class.
new Dog()creates an instance.->accesses its properties and methods.- Inside a method,
$thisrefers to the object the method was called on.
Note that properties are written without the dollar sign after the arrow: $dog->name, not $dog->$name.
Making properties public so outside code can change them freely is fine for a first example; the next lessons show how constructors, visibility and readonly properties keep objects valid.
Each object has its own data
<?php class Counter { public int $value = 0; public function increment(): static { $this->value++; return $this; // returning $this allows chaining } } $a = new Counter(); $b = new Counter(); $a->increment()->increment()->increment(); $b->increment(); echo "a = {$a->value}, b = {$b->value}\n";
a = 3, b = 1
A method that returns $this enables method chaining, a style used by many libraries (query builders, for example).
Objects are passed by handle
Arrays are copied when assigned or passed to functions, but objects aren't: the variable holds a handle to the object, and copying it gives another handle to the same object. A function can therefore change an object it receives:
<?php class Account { public float $balance = 0; } function deposit(Account $account, float $amount): void { $account->balance += $amount; } $mine = new Account(); $alias = $mine; deposit($mine, 100); $alias->balance += 50; echo $mine->balance, "\n"; var_dump($mine === $alias);
150 bool(true)
To get an independent copy, use clone:
<?php class Point { public int $x = 0; public int $y = 0; } $p1 = new Point(); $p2 = clone $p1; $p2->x = 10; echo "{$p1->x} {$p2->x}\n"; var_dump($p1 == $p2, $p1 === $p2);
0 10 bool(false) bool(false)
== compares objects property by property; === checks whether two variables refer to the same object.
Undefined properties
Reading a property that isn't declared gives a warning, and creating one on the fly is deprecated (it will become an error) — another reason to declare every property:
<?php class User { public string $name = "Ana"; } $u = new User(); echo $u->email ?? "(no email)", "\n"; $u->nickname = "ana99";
(no email) Deprecated: Creation of dynamic property User::$nickname is deprecated in main.php on line 10
Inspecting objects
<?php class Book { public string $title = "Dune"; public int $pages = 412; } $book = new Book(); var_dump($book); echo get_class($book), "\n"; var_dump($book instanceof Book); print_r(get_object_vars($book));
object(Book)#1 (2) {
["title"]=>
string(4) "Dune"
["pages"]=>
int(412)
}
Book
bool(true)
Array
(
[title] => Dune
[pages] => 412
)Methods that use other objects
<?php class Point { public float $x = 0; public float $y = 0; public function distanceTo(Point $other): float { return sqrt(($other->x - $this->x) ** 2 + ($other->y - $this->y) ** 2); } } $home = new Point(); $shop = new Point(); $shop->x = 3; $shop->y = 4; echo $home->distanceTo($shop), "\n";
5
Thinking in objects
When designing classes, look for the nouns in a problem — customer, order, invoice, product — as candidate classes, and the verbs — place, cancel, total, ship — as their methods. A good class has one clear responsibility and keeps its data together with the code that changes it.
Try it yourself
Complete a Rectangle class with area, perimeter and isSquare methods.
Area: 10, perimeter: 13 Square? no