PHP::OOP_Mastery
Overview / Session 01
Session 01 of 10  ·  2 hrs + 15 min review

Why OOP? Classes & Objects

⏱ 2-hour session 📋 15-min review 🟢 No prerequisites 🗂 4 topics

1 — Procedural vs Object-Oriented Thinking

Before writing a single class, you need to understand why OOP exists. Procedural code is a list of instructions executed top to bottom. It works fine for small scripts, but as a codebase grows it develops a familiar set of problems: functions that take 10 parameters, global state that anything can modify, and logic scattered across dozens of files with no clear owner.

OOP solves this by grouping data (what a thing is) and behaviour (what a thing does) together into a single unit — the object. Instead of a sprawl of functions operating on loose arrays, you have self-contained entities that manage their own state.

Side-by-side comparison

Imagine tracking a user's name and email and sending them a welcome message.

PHP — Procedural
// Procedural: data is a loose array, functions are global
$user = ['name' => 'Alice', 'email' => 'alice@example.com'];

function sendWelcome(array $user): void
{
    echo "Welcome, {$user['name']}! Check {$user['email']}";
}

sendWelcome($user);
// Nothing stops someone from doing $user['email'] = null anywhere
PHP — Object-Oriented
// OOP: data and behaviour live together, state is protected
class User
{
    public function __construct(
        private string $name,
        private string $email
    ) {}

    public function sendWelcome(): void
    {
        echo "Welcome, {$this->name}! Check {$this->email}";
    }
}

$user = new User('Alice', 'alice@example.com');
$user->sendWelcome();
// $user->email is now inaccessible from outside — it's encapsulated

The OOP version might look like more code today, but it scales. When you need to add a profile picture, a role, or a verification status, you add it to the User class — not hunt through a codebase for every function that touches a $user array.

The four pillars — a quick map

You'll hear these constantly. Know what they mean before you go further:

  • Encapsulation — bundle data + behaviour; hide internal details. (Sessions 1–3)
  • Inheritance — build new classes on top of existing ones. (Session 4)
  • Abstraction — expose only what's necessary; hide implementation. (Session 5)
  • Polymorphism — different objects, same interface, different behaviour. (Sessions 4–5)

2 — Defining Your First Class

A class is a blueprint. A object is a thing built from that blueprint. Think of the class as the cookie cutter; objects are the cookies. One cutter, unlimited cookies — each with its own state (sprinkles, icing) but the same shape.

PHP — Anatomy of a class
/**
 * Class declaration: PascalCase by convention
 * File name must match: Car.php
 */
class Car
{
    // Properties — the data a Car holds
    public string  $make;
    public string  $model;
    public int     $year;
    private int    $speed = 0;   // internal state, hidden from outside

    // Method — the behaviour a Car has
    public function accelerate(int $by): void
    {
        $this->speed += $by;
    }

    public function getSpeed(): int
    {
        return $this->speed;
    }
}

Key syntax rules

  • Class names use PascalCase: BankAccount, UserRepository, EmailSender
  • Each class lives in its own file, named exactly after the class: Car.php
  • Methods use camelCase: getSpeed(), sendEmail()
  • Properties are declared with a type hint and access modifier (PHP 7.4+)
  • The closing brace of a class has no semicolon — that's for interfaces

Adding type declarations (PHP 8+ style)

Modern PHP lets you declare property types directly. This catches bugs at runtime and documents intent far better than a comment ever could.

PHP — Typed properties (PHP 7.4+)
class Product
{
    public string  $name;        // must be string, no null
    public ?string $description; // nullable: string OR null
    public float   $price;
    public int     $stock = 0;   // default value
    public bool    $active = true;
}

If you try to assign a float to $stock, PHP will throw a TypeError immediately — no silent bugs. Always add type hints. They are free documentation and a safety net.

3 — Instantiating Objects with new

You turn a class (blueprint) into an object (real thing) with the new keyword. Each call to new creates a completely independent object with its own copy of the properties.

PHP — Creating and using objects
$car1 = new Car();   // Object #1 — its own speed = 0
$car2 = new Car();   // Object #2 — completely separate

$car1->make  = 'Toyota';
$car1->model = 'Supra';
$car1->accelerate(60);

$car2->make  = 'Honda';
$car2->model = 'NSX';
$car2->accelerate(30);

echo $car1->getSpeed();   // 60 — $car2 is unaffected
echo $car2->getSpeed();   // 30 — $car1 is unaffected

The arrow operator ->

-> is how you access properties and call methods on an object. Think of it as "go to this object and…":

  • $car1->make — read/write the $make property
  • $car1->accelerate(60) — call the accelerate() method

Objects are passed by reference-handle

This is one of the most important things to know early. When you assign an object to a new variable, you're not copying the object — you're copying a handle that points to the same object in memory.

PHP — Reference handles vs clone
$a = new Car();
$a->make = 'BMW';

$b = $a;               // $b points to the SAME object as $a
$b->make = 'Audi';

echo $a->make;          // "Audi" — $a was changed too!

// To get a true copy, use clone:
$c = clone $a;
$c->make = 'Ferrari';

echo $a->make;          // Still "Audi" — clone is a true copy

This trips up every PHP developer at least once. Internalize it now: assignment copies a handle, not the object. Use clone when you need an independent copy.

4 — The Mental Model: Blueprints → Buildings

The blueprint/building metaphor only gets you so far. Here's a more complete mental model that will serve you across the entire course:

Think in nouns, then add verbs

When designing a system, identify the things (nouns) it works with. Each important noun is likely a class. Then figure out what each thing does — those are methods.

PHP — A mini e-commerce model
// Nouns → classes: Product, Cart, Order, Customer, Invoice
// Verbs  → methods on those classes

class Cart
{
    private array $items = [];

    public function addItem(Product $product, int $qty = 1): void
    {
        $this->items[] = ['product' => $product, 'qty' => $qty];
    }

    public function total(): float
    {
        return array_sum(
            array_map(
                fn($i) => $i['product']->price * $i['qty'],
                $this->items
            )
        );
    }

    public function isEmpty(): bool
    {
        return empty($this->items);
    }
}

// Usage reads like plain English:
$cart = new Cart();
$cart->addItem($laptop, 1);
$cart->addItem($mouse,  2);
echo $cart->total();   // price of 1 laptop + 2 mice

Single Responsibility — one class, one job

The most important design rule you'll use every day: a class should have one primary reason to change. A Cart class calculates totals — it doesn't send emails or write to a database. That keeps each class small, testable, and understandable.

  • ❌ UserManagerEmailSenderAndLogger — does too many things
  • ✅ User + Mailer + Logger — each does one thing well

Checking understanding — use instanceof

PHP — instanceof operator
$cart = new Cart();

if ($cart instanceof Cart) {
    echo 'Yes, it is a Cart';
}

// Also works with get_class() and ::class constant:
echo get_class($cart);  // "Cart"
echo Cart::class;       // "Cart" (or full namespace\Cart)

15-Minute Review — Session 01

Stop the session timer and switch to the review timer in the sidebar. Answer these questions from memory — then check.

Q1 — What is the main advantage of OOP over procedural code in large projects?

Q2 — You write $b = $a; where $a is an object. You then set $b->name = 'Bob'. What happens to $a->name?

Q3 — Which of these class names follows PHP convention?

Q4 — What keyword creates a true independent copy of an object in PHP?

✓ Key concepts checklist

Next: Properties, Methods & Visibility →