PHPのオブジェクトの仕組みや使い方について

採用はこちら

PHPのオブジェクトとは、関連するデータと、そのデータを操作する処理をひとまとめにして扱うための仕組みです。

PHPでは、オブジェクト指向プログラミングを利用することで、プログラムを役割ごとに整理しやすくなります。

たとえば、Webサービスの「ユーザー」を表現する場合、名前やメールアドレスといったデータだけでなく、名前を取得する処理やメールアドレスを変更する処理なども同じ単位にまとめられます。

PHPのオブジェクトを理解するうえでは、まず「クラス」「オブジェクト」「インスタンス」という3つの用語を理解することが重要です。

目次

PHPのクラスとオブジェクトの関係

クラスはオブジェクトを定義するための設計図

PHPでは、オブジェクトの構造や機能を定義するものを「クラス」と呼びます。

初心者向けには、クラスを「オブジェクトの設計図」と考えると分かりやすいでしょう。

たとえば、次のようにUserクラスを定義できます。

class User
{
    public string $name;

    public function greet(): string
    {
        return "こんにちは、{$this->name}さん";
    }
}

このコードでは、Userクラスに次の2つを定義しています。

  • $nameというプロパティ
  • greet()というメソッド

プロパティはオブジェクトが保持するデータで、メソッドはオブジェクトが行う処理です。

オブジェクトはクラスから生成する

クラスを定義しただけでは、具体的なユーザー情報を持つオブジェクトはまだ存在しません。

PHPではnewを使ってクラスからオブジェクトを生成します。

$user = new User();

生成したオブジェクトには、次のように値を設定できます。

$user->name = '田中';

echo $user->greet();

実行結果は次のようになります。

こんにちは、田中さん

このように、クラスから生成された個別のオブジェクトを「インスタンス」と呼ぶことがあります。

PHPのプロパティとは

プロパティはオブジェクトが持つデータ

プロパティとは、オブジェクトが保持する値です。

たとえば商品を表すクラスなら、商品名や価格をプロパティとして定義できます。

class Product
{
    public string $name;
    public int $price;
}

オブジェクトを生成したあと、次のように値を設定できます。

$product = new Product();

$product->name = 'キーボード';
$product->price = 5000;

値を取得するときも->を使用します。

echo $product->name;
echo $product->price;

配列とはアクセス方法が異なる

PHPの配列では、次のように値へアクセスします。

$user['name'];

一方、オブジェクトのプロパティへアクセスする場合は次のようになります。

$user->name;

配列では[]、オブジェクトでは基本的に->を使用するという違いがあります。

PHPのメソッドとは

メソッドはクラス内に定義する処理

メソッドとは、クラスの中に定義された関数です。

たとえば、2つの数値を足すメソッドを持つクラスは次のように作れます。

class Calculator
{
    public function add(int $a, int $b): int
    {
        return $a + $b;
    }
}

オブジェクトを生成してメソッドを呼び出します。

$calculator = new Calculator();

echo $calculator->add(10, 20);

結果は次のとおりです。

30

メソッドを利用すると、オブジェクトが持つデータと、そのデータに関連する処理を同じクラスへまとめられます。

PHPの$thisとは

$thisは現在のオブジェクト自身を表す

PHPのオブジェクト指向で頻繁に登場するのが$thisです。

$thisは、現在そのメソッドを実行しているオブジェクト自身を表します。

class User
{
    public string $name;

    public function getName(): string
    {
        return $this->name;
    }
}

次のように利用できます。

$user = new User();
$user->name = '佐藤';

echo $user->getName();

getName()の中にある、

$this->name

は、「現在のオブジェクトが持っているnameプロパティ」という意味です。

PHPのクラスを理解するうえで、$thisは非常に重要なキーワードです。

PHPのコンストラクタとは

__construct()はオブジェクト生成時に呼び出される

コンストラクタとは、新しいオブジェクトを生成するときに呼び出される特殊なメソッドです。

PHPでは__construct()という名前で定義します。

class User
{
    public string $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }
}

オブジェクトを生成するときに値を渡します。

$user = new User('田中');

echo $user->name;

結果は次のようになります。

田中

コンストラクタを利用すると、オブジェクトの生成と同時に必要な初期値を設定できます。

コンストラクタプロパティプロモーション

PHP 8.0以降では、コンストラクタの引数でプロパティを同時に宣言できる「コンストラクタプロパティプロモーション」が利用できます。

class User
{
    public function __construct(
        public string $name,
        public string $email
    ) {
    }
}

次のように使用できます。

$user = new User(
    '田中',
    'tanaka@example.com'
);

echo $user->name;

従来よりも簡潔にプロパティとコンストラクタを記述できるため、現在のPHPではよく利用される書き方です。

PHPのアクセス修飾子とは

public・protected・privateでアクセス範囲を制御する

PHPでは、プロパティやメソッドにアクセスできる範囲をアクセス修飾子で指定できます。

主に次の3種類があります。

アクセス修飾子主なアクセス範囲
publicクラスの内外からアクセスできる
protectedクラス自身と継承関係にあるクラスからアクセスできる
private原則として定義したクラス内部からのみアクセスできる

publicの使い方

publicを指定したプロパティやメソッドには、外部からアクセスできます。

class User
{
    public string $name;
}
$user = new User();

$user->name = '田中';

echo $user->name;

privateの使い方

privateを指定すると、クラスの外部から直接アクセスできません。

class User
{
    private string $name = '田中';

    public function getName(): string
    {
        return $this->name;
    }
}

次のコードは正常に動作します。

$user = new User();

echo $user->getName();

一方、次のようにクラスの外部からprivateプロパティへ直接アクセスすることはできません。

echo $user->name;

protectedの使い方

protectedは、定義したクラスと継承関係にあるクラスで使用できます。

class Animal
{
    protected string $name = '動物';
}

class Dog extends Animal
{
    public function getName(): string
    {
        return $this->name;
    }
}
$dog = new Dog();

echo $dog->getName();

継承を利用するクラス設計でよく使われます。

PHPでgetterとsetterを使う方法

プロパティへのアクセスをメソッド経由にする

プロパティをprivateにし、メソッドを経由して値を取得・変更する設計もあります。

class User
{
    private string $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setName(string $name): void
    {
        $this->name = $name;
    }
}

利用方法は次のとおりです。

$user = new User('田中');

echo $user->getName();

$user->setName('鈴木');

echo $user->getName();

値を取得するメソッドをgetter、値を設定するメソッドをsetterと呼ぶことがあります。

ただし、すべてのプロパティに機械的にgetterとsetterを作る必要はありません。

そのオブジェクトに必要な操作だけを公開することで、より分かりやすく安全なクラス設計につながります。

PHPのオブジェクトに処理を持たせるメリット

データと関連する処理を一か所にまとめられる

オブジェクト指向の大きな特徴は、単にデータを保存するだけでなく、そのデータを使う処理も同じクラスへまとめられることです。

たとえば商品クラスに、税込価格を計算する処理を持たせることができます。

class Product
{
    public function __construct(
        private string $name,
        private int $price
    ) {
    }

    public function getPriceWithTax(float $taxRate): float
    {
        return $this->price * (1 + $taxRate);
    }
}

次のように利用します。

$product = new Product('キーボード', 5000);

echo $product->getPriceWithTax(0.1);

結果は次のとおりです。

5500

商品価格というデータと、その価格を利用する処理をProductという1つの単位にまとめられます。

同じクラスから複数のオブジェクトを生成できる

オブジェクトごとに異なる状態を持てる

同じクラスから複数のオブジェクトを生成できます。

class User
{
    public function __construct(
        public string $name
    ) {
    }
}
$user1 = new User('田中');
$user2 = new User('鈴木');

echo $user1->name;
echo $user2->name;

$user1$user2は同じUserクラスから作られていますが、それぞれ別のオブジェクトです。

そのため、異なるデータを保持できます。

この特徴により、ユーザー、商品、注文など、同じ種類のデータを複数扱いやすくなります。

PHPの継承とは

extendsで既存のクラスを継承する

PHPでは、あるクラスの機能を別のクラスへ引き継ぐ「継承」が利用できます。

class Animal
{
    public function eat(): void
    {
        echo '食べます';
    }
}

class Dog extends Animal
{
    public function bark(): void
    {
        echo 'ワン';
    }
}

DogクラスはAnimalクラスを継承しています。

$dog = new Dog();

$dog->eat();
$dog->bark();

Dogクラスには直接eat()が定義されていませんが、親クラスから引き継いでいるため利用できます。

メソッドをオーバーライドできる

子クラスでは、親クラスのメソッドを条件に従って再定義できます。

class Animal
{
    public function speak(): string
    {
        return '鳴きます';
    }
}

class Dog extends Animal
{
    public function speak(): string
    {
        return 'ワン';
    }
}
$dog = new Dog();

echo $dog->speak();

結果は次のとおりです。

ワン

このように、親クラスのメソッドを子クラス側で再定義することを「オーバーライド」と呼びます。

PHPのインターフェースとは

implementsで共通ルールを定義する

PHPでは、クラスが実装すべき機能を定めるためにインターフェースを利用できます。

interface PaymentInterface
{
    public function pay(int $amount): void;
}

インターフェースを実装するクラスではimplementsを使用します。

class CreditCardPayment implements PaymentInterface
{
    public function pay(int $amount): void
    {
        echo "{$amount}円をクレジットカードで支払います";
    }
}

次のように利用できます。

$payment = new CreditCardPayment();

$payment->pay(5000);

インターフェースを使うと、異なるクラスに共通したルールを持たせやすくなります。

たとえば、

CreditCardPayment
BankTransferPayment
ElectronicMoneyPayment

のように実装方法が異なっていても、すべてpay()という共通した操作を提供する設計ができます。

PHPの抽象クラスとは

abstractで共通処理と実装ルールをまとめる

PHPではabstractを使って抽象クラスを作れます。

abstract class Animal
{
    abstract public function speak(): string;

    public function sleep(): string
    {
        return '眠ります';
    }
}

子クラスで抽象メソッドを実装します。

class Dog extends Animal
{
    public function speak(): string
    {
        return 'ワン';
    }
}
$dog = new Dog();

echo $dog->speak();
echo $dog->sleep();

抽象クラスでは、子クラスに実装を求めるメソッドと、共通して利用する実装済みメソッドの両方を持たせられます。

なお、抽象クラス自体を直接newしてオブジェクトを生成することはできません。

PHPのstaticメソッドとは

オブジェクトを生成せずに呼び出せる

通常のインスタンスメソッドは、オブジェクトを生成してから呼び出します。

$calculator = new Calculator();

$calculator->add(10, 20);

一方、staticメソッドはクラスそのものに関連付けられたメソッドです。

class Calculator
{
    public static function add(int $a, int $b): int
    {
        return $a + $b;
    }
}

次のように呼び出せます。

echo Calculator::add(10, 20);

staticメンバーへアクセスするときは、基本的に::を使用します。

ただし、個々のオブジェクトが持つ状態を利用する処理まで何でもstaticにするのは適切ではありません。

オブジェクトごとのデータを扱う場合は、通常のインスタンスメソッドとして設計するほうが自然です。

PHPのオブジェクトと配列の違い

配列は柔軟にデータをまとめられる

PHPでは、配列を使って複数のデータをまとめることもできます。

$user = [
    'name' => '田中',
    'email' => 'tanaka@example.com',
];

次のようにアクセスします。

echo $user['name'];

オブジェクトは構造や処理を明確にしやすい

同じデータをオブジェクトで表現すると次のようになります。

class User
{
    public function __construct(
        public string $name,
        public string $email
    ) {
    }
}
$user = new User(
    '田中',
    'tanaka@example.com'
);

echo $user->name;

配列とオブジェクトには、それぞれ適した用途があります。

一時的なデータや柔軟なデータ構造には配列が便利です。

一方、ユーザー、商品、注文など、明確な構造やルール、処理を持たせたい場合はオブジェクトが適していることがあります。

PHPでオブジェクトの型を指定する方法

クラス名を型として利用できる

PHPでは、関数やメソッドの引数にクラス名を型として指定できます。

class User
{
    public function __construct(
        public string $name
    ) {
    }
}
function showUserName(User $user): void
{
    echo $user->name;
}

使用例は次のとおりです。

$user = new User('田中');

showUserName($user);

戻り値にもクラスを型として指定できます。

function createUser(): User
{
    return new User('田中');
}

型を明示すると、どのようなオブジェクトを受け取ったり返したりする処理なのか分かりやすくなります。

PHPのinstanceofとは

オブジェクトの種類を確認できる

instanceofを使用すると、変数が特定のクラスやインターフェースに該当するオブジェクトか確認できます。

$user = new User('田中');

if ($user instanceof User) {
    echo 'Userオブジェクトです';
}

インターフェースについて確認することもできます。

if ($payment instanceof PaymentInterface) {
    echo 'PaymentInterfaceを実装しています';
}

複数種類のオブジェクトを扱う処理などで役立ちます。

PHPでオブジェクトを代入するときの注意点

代入しても新しいオブジェクトが自動的に複製されるわけではない

PHPでは、オブジェクトを別の変数へ代入しても、新しい独立したオブジェクトが自動的に作られるわけではありません。

class User
{
    public string $name;
}

$user1 = new User();
$user1->name = '田中';

$user2 = $user1;

$user2->name = '鈴木';

echo $user1->name;

実行すると、$user1->name鈴木になります。

$user1$user2の両方から同じオブジェクトインスタンスへアクセスしているためです。

なお、これはPHPの&を使う「参照」と完全に同じ意味ではありません。

オブジェクトの代入とPHPの参照機能は区別して理解することが重要です。

PHPでオブジェクトをcloneする方法

cloneで別のオブジェクトを作成する

独立したオブジェクトとして複製したい場合はcloneを使用します。

$user2 = clone $user1;

これにより、$user1$user2は別のオブジェクトになります。

ただし、PHPのcloneは基本的に浅いコピーです。

プロパティの中に別のオブジェクトが入っている場合、その内部オブジェクトまで自動的に完全複製されるわけではありません。

必要に応じて__clone()を使って複製時の処理を定義できます。

public function __clone(): void
{
    $this->child = clone $this->child;
}

複雑なオブジェクトを複製する場合は、この点に注意が必要です。

PHPのstdClassとは

汎用的なオブジェクトを簡単に作れる

PHPにはstdClassという汎用的な空のクラスがあります。

$user = new stdClass();

$user->name = '田中';
$user->age = 30;

echo $user->name;

簡単なオブジェクトを作成したい場合などに利用できます。

json_decode()でもstdClassが使われる

JSONをPHPのオブジェクトとしてデコードした場合にもstdClassが利用されることがあります。

$json = '{"name":"田中","age":30}';

$user = json_decode($json);

echo $user->name;

一方、第2引数にtrueを指定すると、連想配列として取得できます。

$user = json_decode($json, true);

echo $user['name'];

動的プロパティには注意する

stdClassでは、次のように後からプロパティを追加できます。

$user->name = '田中';

ただし、一般的なユーザー定義クラスでも未定義のプロパティを自由に追加すればよいという意味ではありません。

現代的なPHPでは、必要なプロパティをクラス内で明示的に宣言する設計が基本です。

class User
{
    public string $name;
}

stdClassの使い方と通常のクラス設計は分けて考えたほうがよいでしょう。

PHPのオブジェクト指向を使うメリット

コードの役割を整理しやすい

ユーザー関連の処理をUserクラス、商品関連の処理をProductクラスのように分けることで、コードの役割を整理できます。

たとえば、

User
├─ 名前
├─ メールアドレス
├─ 名前を取得する処理
└─ メールアドレスを変更する処理

という形で関連するデータと処理をまとめられます。

データを安全に管理しやすい

privateなどを利用すると、外部から勝手に値を変更されることを防ぎやすくなります。

たとえば、商品の価格を負数にしたくない場合は次のように制御できます。

class Product
{
    private int $price;

    public function setPrice(int $price): void
    {
        if ($price < 0) {
            throw new InvalidArgumentException(
                '価格は0以上にしてください'
            );
        }

        $this->price = $price;
    }
}

このように、データだけでなく「どのような値を許可するか」というルールもクラス内にまとめられます。

コードを再利用しやすい

適切にクラスを設計すると、同じ処理を複数の場所で再利用しやすくなります。

継承やインターフェース、traitなどを利用すれば、より柔軟な設計も可能です。

大規模なプログラムを管理しやすい

小規模なPHPスクリプトであれば、関数だけでも十分な場合があります。

しかし、機能が増えてくると、すべての処理を1か所へ書く方法では管理が難しくなります。

オブジェクト指向で役割ごとにクラスを分けることで、大規模なアプリケーションでも構造を理解しやすくなります。

PHPオブジェクトの実践的な使用例

商品を表すProductクラスを作る

ECサイトの商品を表すクラスを例に考えてみます。

class Product
{
    public function __construct(
        private string $name,
        private int $price
    ) {
        if ($price < 0) {
            throw new InvalidArgumentException(
                '価格は0以上で指定してください'
            );
        }
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getPrice(): int
    {
        return $this->price;
    }

    public function getPriceWithTax(float $taxRate): float
    {
        return $this->price * (1 + $taxRate);
    }
}

オブジェクトを生成します。

$product = new Product(
    'キーボード',
    5000
);

商品名を取得できます。

echo $product->getName();

価格を取得できます。

echo $product->getPrice();

税込価格も計算できます。

echo $product->getPriceWithTax(0.1);

この例では、

  • 商品名
  • 商品価格
  • 商品名を取得する処理
  • 価格を取得する処理
  • 税込価格を計算する処理

Productクラスへまとめています。

単純な連想配列と比べて、「商品がどのような情報と機能を持っているのか」が分かりやすくなります。

PHPオブジェクトで覚えておきたい用語

基本用語を整理する

PHPのオブジェクトを学習するときは、次の用語を押さえておくと理解しやすくなります。

用語意味
クラスオブジェクトの構造や機能を定義するもの
オブジェクトクラスから生成された実体
インスタンスクラスから生成された個別のオブジェクト
プロパティオブジェクトが持つデータ
メソッドクラス内に定義された処理
$this現在のオブジェクト自身
newオブジェクトを生成する
->オブジェクトのプロパティやメソッドへアクセスする
::staticメンバーなどへアクセスする
extendsクラスを継承する
implementsインターフェースを実装する
instanceofオブジェクトの型などを確認する
cloneオブジェクトを複製する

初心者の場合は、まず次の流れを理解するとよいでしょう。

クラスを定義
↓
newでオブジェクトを生成
↓
プロパティに値を保持
↓
メソッドで処理を実行

PHPのオブジェクトを使う際の注意点

何でもクラスにすればよいわけではない

オブジェクト指向は便利ですが、すべての処理をクラスにする必要はありません。

単純な値の変換や短い処理であれば、通常の関数のほうが分かりやすい場合もあります。

クラス化そのものを目的にするのではなく、コードを整理しやすくするために利用することが重要です。

publicプロパティを増やしすぎない

すべてのプロパティをpublicにすると、クラスの外部から自由に変更できるようになります。

オブジェクト内部の状態を適切に管理したい場合は、privateprotectedを利用し、必要な操作だけをメソッドとして公開するとよいでしょう。

1つのクラスに役割を詰め込みすぎない

1つのクラスに多くの責務を持たせると、コードの管理が難しくなります。

たとえば、1つのクラスですべてを行うよりも、

商品管理
決済処理
メール送信
データベース処理
ログ出力

などを適切な単位に分けたほうが、保守しやすい設計になる場合があります。

現代的なPHPで知っておきたいオブジェクト指向機能

readonly

PHPには、値の変更を制限するためのreadonly機能があります。

オブジェクト生成後に変更させたくない値を扱う場合などに利用できます。

PHPの基本的なオブジェクトを理解したあとに学習するとよい機能です。

trait

PHPには、複数のクラスで実装を再利用するためのtraitがあります。

継承だけに頼らず、複数のクラスで共通するメソッドを共有したい場合などに利用できます。

Property Hooksなどの新しい機能

近年のPHPでは、オブジェクト指向に関する機能が継続的に追加されています。

ただし、最初から最新機能をすべて覚える必要はありません。

まずはクラス、オブジェクト、プロパティ、メソッド、$this、コンストラクタ、アクセス修飾子を理解することが重要です。

PHPのオブジェクトを学習するおすすめの順番

基礎から段階的に学ぶ

PHPのオブジェクト指向を学習する場合は、次の順番で進めると理解しやすくなります。

  1. クラスとオブジェクトの違い
  2. newによるオブジェクト生成
  3. プロパティ
  4. メソッド
  5. $this
  6. コンストラクタ
  7. publicprotectedprivate
  8. 型宣言
  9. 継承
  10. インターフェース
  11. 抽象クラス
  12. instanceof
  13. clone
  14. trait
  15. 名前空間やComposer
  16. DIなどのアプリケーション設計

特に、最初は次のような基本コードを理解できるようになることを目標にするとよいでしょう。

class User
{
    public function __construct(
        private string $name
    ) {
    }

    public function getName(): string
    {
        return $this->name;
    }
}

$user = new User('田中');

echo $user->getName();

このコードを理解できれば、PHPのオブジェクト指向を学ぶための基礎はかなり身についていると考えられます。

PHPのオブジェクトについてのまとめ

PHPのオブジェクトとは、関連するデータと処理を1つのまとまりとして扱うための仕組みです。

クラスで構造や機能を定義し、newを使って具体的なオブジェクトを生成します。

生成したオブジェクトのプロパティやメソッドには、基本的に次のようにアクセスします。

$object->property;
$object->method();

PHPではさらに、コンストラクタ、アクセス修飾子、継承、インターフェース、抽象クラス、型宣言、instanceofcloneなどを利用できます。

こうした機能を組み合わせることで、コードの役割やデータの扱い方を明確にし、大規模なプログラムでも管理しやすい構造を作れます。

ただし、オブジェクト指向の目的は、単にクラスを増やすことではありません。

関連するデータと処理を適切な単位にまとめ、プログラムを理解・変更・再利用しやすくすることが重要です。

PHPで本格的なWebアプリケーションを開発する場合は、まずクラス、オブジェクト、プロパティ、メソッド、$this、コンストラクタ、アクセス修飾子をしっかり理解し、その後に継承やインターフェースなどへ進むと理解しやすいでしょう。

以上、PHPのオブジェクトの仕組みや使い方についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次