【サクッと解説】PHP アクセス修飾子の使い分け(public / private / protected)

目次

1. 本記事のポイント

  • PHPのアクセス修飾子(public / protected / private)の基本的な意味と違いを整理
  • 実務での使い分けと、設計意図に基づく選択基準を明示
  • 間違いやすい継承時の挙動やアクセス制限の盲点も補足

2. PHPのアクセス修飾子とは?

PHPにおけるアクセス修飾子(アクセス権)は、クラス内部のプロパティやメソッドの外部からの参照可能範囲を制御するための機能です。主に「カプセル化(情報隠蔽)」を実現するために使われます。

PHPでは以下の3種類が定義されています:

  • public: どこからでもアクセス可能(外部・継承先・クラス内)
  • protected: 同一クラスおよび継承先クラスからのみアクセス可能
  • private: 宣言されたクラス内からのみアクセス可能(継承先でも不可)

この機能により、内部的な処理を隠蔽したり、意図しない使い方を防ぐことができます。特に大規模アプリケーションでは、意図しない副作用の抑制や保守性向上に寄与します。

3. 詳細解説

基本的な使い分け:どこからアクセスさせたいかで選ぶ

まずは、アクセス修飾子の違いをシンプルなクラス定義で確認します。

PHP
class Sample {
    public $a = "公開";          // どこからでもアクセス可能
    protected $b = "保護";       // 継承先までアクセス可能
    private $c = "非公開";       // 同一クラス内のみ

    public function showAll() {
        echo $this->a; // OK
        echo $this->b; // OK
        echo $this->c; // OK
    }
}

$obj = new Sample();
echo $obj->a;     // OK
// echo $obj->b;  // エラー: protected
// echo $obj->c;  // エラー: private

継承時の挙動:protectedとprivateの違い

継承時のアクセス制限の差を明確にするため、以下のような例を見てみましょう。

PHP
class ParentClass {
    protected $val1 = "継承OK";
    private $val2 = "継承不可";
}

class ChildClass extends ParentClass {
    public function display() {
        echo $this->val1; // OK
        // echo $this->val2; // エラー: privateは継承先でアクセス不可
    }
}

このように、protected は継承先クラスからアクセス可能ですが、private は完全に外部非公開であるため、継承先からも見えません。

メソッドにも使える:内部専用メソッドの隠蔽

メソッドにもアクセス修飾子を指定できます。外部に見せたくない処理ロジックを private にすることで、意図しない利用を防げます。

PHP
class Logger {
    public function log($msg) {
        $this->writeLog($msg);
    }

    private function writeLog($msg) {
        echo "[LOG] $msg";
    }
}

$logger = new Logger();
$logger->log("処理開始");       // OK
// $logger->writeLog("直接呼び出し"); // エラー

このように、公開インターフェースを public に限定し、それ以外の処理は private または protected にすることで、APIの明確化と安全性が高まります。

4. よくあるミス・誤解・落とし穴

privateなプロパティの再定義による混乱

親クラスと子クラスで同じ名前の private プロパティを定義すると、完全に別物として扱われ、予期しない挙動を引き起こす可能性があります。

PHP
class Base {
    private $val = "base";
    public function getVal() {
        return $this->val;
    }
}

class Sub extends Base {
    private $val = "sub";
}

$obj = new Sub();
echo $obj->getVal(); // "base" が出力される("sub" ではない)

このように、同じ $val でもスコープが異なるため、上書きや参照の意図が反映されません。

protectedを使ったつもりが、アクセスエラーになるケース

継承関係にあるクラス間でも、意図せず private を指定してしまうと、アクセスできずに例外が発生します。

そのため、継承先で利用を前提とする場合は protected を選ぶのが基本です。

5. まとめ

  • public は外部公開、protected は継承前提、private は完全に非公開
  • 実務では「外部APIなのか」「内部実装なのか」で使い分けるのが基本
  • クラス設計時は、公開範囲を意図的に狭める方が安全
  • 継承時の private の扱いや、同名プロパティの再定義には注意が必要
よかったらシェアしてね!
  • URLをコピーしました!
目次