🐘

PHP における self::method と $this->method の違いは?

に公開

PHPにおけるself::method$this->methodの違い

1. アクセス対象の違い

  • self::method
    静的メソッド/プロパティ専用。クラス定数やstatic宣言されたメンバにアクセスします。

    class Example {
        public static function staticMethod() {
            return 'static';
        }
        public function show() {
            echo self::staticMethod(); // 静的メソッド呼び出し
        }
    }
    
  • $this->method
    インスタンスメソッド/プロパティ専用。オブジェクト生成後に利用可能な通常メンバにアクセスします。

    class Example {
        public function instanceMethod() {
            return 'instance';
        }
        public function show() {
            echo $this->instanceMethod(); // インスタンスメソッド呼び出し
        }
    }
    

2. 動作特性の違い

項目 self::method $this->method
呼び出しタイミング クラス定義時 インスタンス生成後
オーバーライド 親クラスのメソッドを直接呼び出し 子クラスでオーバーライド可能
エラー発生条件 インスタンスメソッドを呼ぶとエラー 静的メソッドを呼ぶとエラー

3. 継承時の挙動

  • self::method
    定義されたクラスのメソッドを常に呼び出し(遅延静的バインディング不可)。

    class ParentClass {
        public static function test() {
            self::who(); // ParentClassのwho()を呼び出す
        }
        public static function who() {
            echo 'parent ';
        }
    }
    
    class ChildClass extends ParentClass {
        public static function who() {
            echo 'child ';
        }
    }
    
    ChildClass::test(); // 出力結果: parent
    
  • $this->method
    実際のインスタンスのメソッドを呼び出し(オーバーライド反映)。

    class ParentClass {
        public function test() {
            $this->who(); // 実際のインスタンスのwho()を呼び出す
        }
        public function who() {
            echo 'parent ';
        }
    }
    
    class ChildClass extends ParentClass {
        public function who() {
            echo 'child ';
        }
    }
    
    $obj = new ChildClass();
    $obj->test(); // 出力結果: child
    

4. 主な使用場面

  • self::を使うケース

    • 静的ファクトリメソッドの実装
    • クラス定数へのアクセス
    • シングルトンパターン実装
  • $this->を使うケース

    • インスタンス間で異なる値を持つプロパティ操作
    • ポリモーフィズムを活かした設計

5. エラー例

class Test {
    public static $staticVar = 'static';
    public $instanceVar = 'instance';

    public function show() {
        echo self::$instanceVar;    // エラー(非staticプロパティ)
        echo $this->staticVar;      // エラー(staticプロパティ)
    }
}

要約:
self::クラス定義時の静的な要素に、$this->インスタンス生成後の動的な要素にアクセスします。継承時の挙動の違いが特に重要で、オーバーライドの有無が結果に直結します。

Discussion