PHP: Classes and Objects

You've written 21 lessons of procedural code, and you're probably starting to feel that things get messy as your codebase grows. Object-oriented programming (OOP) solves this problem—it bundles related data and functions into "classes," making code more organized and reusable.

1. Why Do We Need Classes and Objects?

Think of it with a real-world analogy:

TEXT 📖 参照専用
Procedural: You follow a checklist every time you bake a cake — crack eggs → add flour → mix → bake
Object-oriented: You have a "cake machine" (class). Press "make" and out comes a cake (object)

Let's compare code:

PHP
<?php
// Procedural: data and functions are scattered
$userName = "John";
$userAge = 25;
function greet($name) {
    return "Hello, {$name}";
}
echo greet($userName);

// Object-oriented: data and functions are bundled together
class User {
    public string $name;
    public int $age;
    
    function greet(): string {
        return "Hello, {$this->name}";
    }
}
$user = new User();
$user->name = "John";
$user->age = 25;
echo $user->greet();
?>
💡 Tip: OOP isn't a "better" way to program—it's a tool for organizing complex code. Small scripts are simpler with procedural code. The advantages of OOP become clear once your codebase exceeds 500 lines.


2. Defining a Class

PHP
<?php
class Car {
    // Properties (data)
    public string $brand;
    public string $color;
    public int $year;
    
    // Methods (behavior)
    public function start(): string {
        return "{$this->brand} is starting!";
    }
    
    public function honk(): string {
        return "Beep beep!";
    }
}
?>

Key syntax points:


3. Creating Objects

A class is just a "blueprint." You create concrete "objects" with the new keyword:

PHP
<?php
// From one blueprint (class), create three specific cars (objects)
$car1 = new Car();
$car1->brand = "Toyota";
$car1->color = "White";
$car1->year = 2024;

$car2 = new Car();
$car2->brand = "BMW";
$car2->color = "Black";
$car2->year = 2023;

echo $car1->start();  // Toyota is starting!
echo $car2->start();  // BMW is starting!

// Use the arrow operator -> to access properties and methods
echo $car1->brand;    // Toyota
$car1->color = "Red"; // Modify a property
echo $car1->color;    // Red
?>

4. The __construct Method

The constructor is called automatically when you use new, letting you initialize an object:

PHP
<?php
class Car {
    public string $brand;
    public string $color;
    public int $year;
    
    // Constructor
    public function __construct(string $brand, string $color, int $year) {
        $this->brand = $brand;
        $this->color = $color;
        $this->year  = $year;
    }
    
    public function getInfo(): string {
        return "{$this->year} {$this->color} {$this->brand}";
    }
}

// Pass arguments when creating the object
$car = new Car("Toyota", "White", 2024);
echo $car->getInfo();  // 2024 White Toyota
?>
💡 Tip: In $this->brand = $brand, the left side $this->brand is the property and the right side $brand is the parameter. PHP 8.0+ supports constructor property promotion, which makes this even cleaner—see below.

▶ サンプル: PHP 8 Constructor Property Promotion

PHP
<?php
// PHP 8.0+ simplified syntax
class Car {
    public function __construct(
        public string $brand,
        public string $color,
        public int $year,
    ) {
        // Parameters automatically become properties! No more $this->brand = $brand
    }
}

$car = new Car("Toyota", "White", 2024);
echo $car->brand;  // Toyota ✅
?>
▶ 試してみよう
💡 Tip: This is one of PHP 8's biggest improvements—constructor property promotion cuts boilerplate in half. New projects should use this syntax.


5. Access Modifiers

Access modifiers control the visibility of properties and methods:

PHP
<?php
class BankAccount {
    public string $bank = "Bank of China";  // Anyone can see and modify
    private float $balance = 0;             // Only accessible inside the class
    protected string $accountId;            // Accessible inside the class and subclasses
    
    public function __construct(
        private string $owner,
        private float $initialDeposit = 0.0
    ) {
        $this->balance = $initialDeposit;
    }
    
    // Safely manipulate private properties through public methods
    public function deposit(float $amount): void {
        if ($amount > 0) {
            $this->balance += $amount;
        }
    }
    
    public function getBalance(): float {
        return $this->balance;
    }
}

$account = new BankAccount("John", 1000);
echo $account->bank;         // Bank of China ✅ public is accessible
$account->deposit(500);       // ✅ public method can be called
echo $account->getBalance(); // 1500 ✅
// echo $account->balance;   // ❌ Error: private property not directly accessible
// $account->balance = 9999; // ❌ Error: can't arbitrarily change the balance
?>
Modifier Alias Access Scope
public Public Accessible everywhere
protected Protected Current class and subclasses
private Private Current class only
💡 Tip: Make properties private or protected and access them through public methods—this is called encapsulation. It lets you control how data is modified, for example, deposit() can include validation.


6. Comparing Objects

PHP
<?php
class User {
    public function __construct(
        public string $name,
        public int $age
    ) {}
}

$u1 = new User("John", 25);
$u2 = new User("John", 25);
$u3 = $u1;

var_dump($u1 == $u2);   // true (same property values)
var_dump($u1 === $u2);  // false (not the same object)
var_dump($u1 === $u3);  // true (pointing to the same object)
?>

7. Complete Example: A User Class

▶ サンプル: A Complete User Class

PHP
<?php
class User {
    private string $passwordHash;  // Password hash—never exposed
    
    public function __construct(
        public string $username,
        public string $email,
        string $password,           // Regular parameter (not a property)
        public int $age = 0,
        public bool $isActive = true,
    ) {
        // Password is hashed during construction
        $this->passwordHash = password_hash($password, PASSWORD_DEFAULT);
    }
    
    public function verifyPassword(string $password): bool {
        return password_verify($password, $this->passwordHash);
    }
    
    public function getDisplayName(): string {
        return $this->username . ($this->isActive ? '' : ' (Deactivated)');
    }
    
    public function greet(): string {
        return "Hello, {$this->username}! Your email is {$this->email}.";
    }
}

// Usage
$user = new User("John", "john@example.com", "secret123", 25);

echo $user->greet();
echo "User status: " . $user->getDisplayName() . "<br>";

if ($user->verifyPassword("secret123")) {
    echo "Password correct!";
}
// echo $user->passwordHash; // ❌ Error: private, not accessible
?>
▶ 試してみよう

❓ よくある質問

Q When should I use a class vs. a function?
A Use a class when data and the functions that operate on it naturally belong together. For example, a "user" has name/age/email properties and login/logout methods. If you just have a few unrelated utility functions, plain functions are fine.
Q What is $this?
A $this is a reference to "the current object being operated on" inside an object method. For instance, inside $car1->start(), $this refers to $car1.
Q Why not use var to declare properties?
A That's PHP 4 syntax and it's obsolete. Modern PHP always uses public/private/protected with type declarations.

📖 まとめ

📝 練習問題

  1. Create a Book class with properties title/author/price, a constructor to initialize them, and a getInfo() method that returns book information.
  2. Create a BankAccount class with a private balance, public deposit and withdraw methods (withdrawals can't exceed the balance), and a public method to check the balance. Create a few accounts and test operations.
  3. Rewrite exercise 1 using PHP 8 constructor property promotion. See how many lines of code you save.
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%