The 4 Pillars
- Encapsulation is about keeping an object's internal state private and exposing a controlled API (methods / controlled property access). In PHP you use private/protected/public, and asymmetric property visibility for read/write control.
class BankAccount { private float $balance = 0.0; public function deposit(float $amount): void { if ($amount <= 0) { throw new InvalidArgumentException('Amount > 0'); } $this->balance += $amount; } public function getBalance(): float { return $this->balance; } } $acc = new BankAccount(); $acc->deposit(100.0); echo $acc->getBalance(); // 100
- Inheritance lets one class extend another and reuse/override behaviour. extends copies public/protected members (private members are not inherited directly). Use parent::method() to call the parent implementation.
class Vehicle { public function move(): void { echo "The vehicle is moving"; } } class Car extends Vehicle { public function move(): void { echo "The car drives on the road"; } } class Boat extends Vehicle { public function move(): void { echo "The boat sails on the water"; } } $vehicle = new Vehicle(); $vehicle->move(); // The vehicle is moving $car = new Car(); $car->move(); // The car drives on the road $boat = new Boat(); $boat->move(); // The boat sails on the water
- Polymorphism describes using a common interface or base class so objects of different concrete types can be used interchangeably (Liskov Substitution Principle).
interface PaymentMethod { public function pay(float $amount): void; } class CreditCardPayment implements PaymentMethod { public function pay(float $amount): void { echo "Paid ${amount} using Credit Card"; } } class PayPalPayment implements PaymentMethod { public function pay(float $amount): void { echo "Paid ${amount} via PayPal"; } } class CryptoPayment implements PaymentMethod { public function pay(float $amount): void { echo "Paid ${amount} in Bitcoin"; } } function processPayment(PaymentMethod $method, float $amount): void { $method->pay($amount); } processPayment(new CreditCardPayment(), 100.0); // Paid $100 using Credit Card processPayment(new PayPalPayment(), 50.5); // Paid $50.5 via PayPal processPayment(new CryptoPayment(), 250.0); // Paid $250 in Bitcoin
- Abstraction: Abstract classes and interfaces declare an API without providing full implementation. Use abstract class for partial implementations, interface for pure contracts.
interface Renderer { public function render(array $data): string; } class HtmlRenderer implements Renderer { public function render(array $data): string { // produce HTML return '<pre>' . htmlspecialchars(json_encode($data, JSON_THROW_ON_ERROR)) . '</pre>'; } }
Properties
- Property Type Declarations
Typed properties enforce runtime type rules and reduce bugs.
class Product { public int $id; public ?string $title = null; // nullable }
- Union Types
You can declare union types:
class Example { public int|string $id; }
- Readonly Properties
readonly properties can be set once (usually in the constructor) and then cannot be reassigned.
class User { public readonly int $id; public function __construct(int $id) { $this->id = $id; } }
- Constructor Property Promotion
You can declare class properties directly in the constructor parameter list:
class DTO { public function __construct( public int $id, private string $name, protected ?DateTimeImmutable $createdAt = null ) {} }
This declares the properties and initialises them - less boilerplate.
- Property Hooks
Property hooks (sometimes called property accessors) let you define get and/or set behavior on a particular property (not via __get/__set magic for all unknowns). Hooks allow virtual properties (no actual storage) and fine control over per-property behavior.
Key points:
class Example { private bool $modified = false; public string $foo = 'default value' { get { if ($this->modified) { return $this->foo . ' (modified)'; } return $this->foo; } set(string $value) { $this->foo = strtolower($value); $this->modified = true; } } } $example = new Example(); $example->foo = 'changed'; print $example->foo; // changed (modified)
Class Constants
test
Source: Orkhan Alishov's notes