基礎

PHPのクラス入門|オブジェクト指向の基本を理解する

PHPのクラス(class)は、データ(プロパティ)と処理(メソッド)をひとまとめにした設計図です。クラスから生成された実体をオブジェクト(インスタンス)と呼びます。オブジェクト指向プログラミング(OOP)の最も基本的な構成要素です。

関数だけのプログラムでは、データと処理が分離して管理が難しくなりますが、クラスを使うことでデータと関連する処理をまとめて管理でき、大規模なアプリケーション開発に不可欠な機能です。

基本的な使い方

class キーワードでクラスを定義し、new でインスタンスを生成します。

PHP
<?php
class User {
    // プロパティ(データ)
    public string $name;
    public int $age;

    // メソッド(処理)
    public function greet(): string {
        return "こんにちは、{$this->name}です。{$this->age}歳です。";
    }
}

// インスタンスの生成
$user = new User();
$user->name = "田中";
$user->age = 30;

echo $user->greet() . "\n";
実行結果
こんにちは、田中です。30歳です。

User クラスには $name$age という2つのプロパティ、greet() というメソッドがあります。new User() でインスタンスを生成し、-> 演算子でプロパティやメソッドにアクセスします。

コンストラクタを使った初期化

__construct() メソッドを定義すると、インスタンス生成時に自動的に呼ばれ、初期化処理を行えます。

PHP
<?php
class Product {
    public string $name;
    public int $price;
    public int $stock;

    public function __construct(string $name, int $price, int $stock = 0) {
        $this->name = $name;
        $this->price = $price;
        $this->stock = $stock;
    }

    public function getInfo(): string {
        return "{$this->name}: {$this->price}円(在庫: {$this->stock}個)";
    }
}

$product1 = new Product("PHP入門書", 2980, 50);
$product2 = new Product("ノート", 150);

echo $product1->getInfo() . "\n";
echo $product2->getInfo() . "\n";
実行結果
PHP入門書: 2980円(在庫: 50個)
ノート: 150円(在庫: 0個)

コンストラクタプロモーション(PHP 8.0+)

PHP 8.0以降では、コンストラクタの引数にアクセス修飾子を付けることで、プロパティの宣言と代入を同時に行えます。

PHP
<?php
class Point {
    // コンストラクタプロモーション
    public function __construct(
        public float $x,
        public float $y,
        public float $z = 0.0
    ) {}

    public function distanceTo(Point $other): float {
        return sqrt(
            ($this->x - $other->x) ** 2 +
            ($this->y - $other->y) ** 2 +
            ($this->z - $other->z) ** 2
        );
    }
}

$p1 = new Point(0, 0);
$p2 = new Point(3, 4);
echo "距離: " . $p1->distanceTo($p2) . "\n";
実行結果
距離: 5

複数のインスタンス

1つのクラスから複数のインスタンスを生成でき、それぞれ独立したデータを持ちます。

PHP
<?php
class Counter {
    private int $count = 0;

    public function increment(): void {
        $this->count++;
    }

    public function getCount(): int {
        return $this->count;
    }
}

$counterA = new Counter();
$counterB = new Counter();

$counterA->increment();
$counterA->increment();
$counterA->increment();
$counterB->increment();

echo "A: " . $counterA->getCount() . "\n";
echo "B: " . $counterB->getCount() . "\n";
実行結果
A: 3
B: 1

実用的な例

PHP
<?php
class ShoppingCart {
    private array $items = [];

    public function addItem(string $name, int $price, int $qty = 1): void {
        $this->items[] = compact("name", "price", "qty");
    }

    public function getTotal(): int {
        $total = 0;
        foreach ($this->items as $item) {
            $total += $item["price"] * $item["qty"];
        }
        return $total;
    }

    public function showCart(): void {
        foreach ($this->items as $item) {
            $subtotal = $item["price"] * $item["qty"];
            echo "  {$item['name']} x{$item['qty']} = {$subtotal}円\n";
        }
        echo "  合計: {$this->getTotal()}円\n";
    }
}

$cart = new ShoppingCart();
$cart->addItem("りんご", 150, 3);
$cart->addItem("バナナ", 200, 2);
$cart->addItem("みかん", 100, 5);
$cart->showCart();
実行結果
  りんご x3 = 450円
  バナナ x2 = 400円
  みかん x5 = 500円
  合計: 1350円
ポイント

クラス名は慣例としてアッパーキャメルケース(PascalCase)で命名します。1ファイルに1クラスを定義し、ファイル名をクラス名と合わせるのがPSR(PHPコーディング規約)の推奨です。

注意

プロパティを public にすると外部から自由に変更できてしまいます。データの整合性を保つには private で宣言し、メソッド経由でアクセスする(カプセル化)のが推奨されます。

まとめ

  • class でデータ(プロパティ)と処理(メソッド)を1つにまとめる
  • new でインスタンスを生成し、-> でアクセスする
  • __construct() で初期化処理を自動実行できる
  • PHP 8.0のコンストラクタプロモーションで記述を大幅に簡略化できる
  • 各インスタンスは独立したデータを持ち、同じメソッドを共有する