【PHP】parent で親クラスのメソッドを呼ぶ時と直接クラスを指定して親クラスのメソッドを呼ぶ時で挙動が違う

  • 2022年8月1日
  • PHP

 題の通りです。端的に言うと親クラスでstatic::を使って子クラス配下の静的なメソッドなりクラス名なりを呼ぶ時の挙動が変わります。これの対策には常にparent::を使うことです。概ね直感的な挙動をしてくれます。

 挙動の違いの具体例は次です。

<?php

class A {
    public static function echoClass(): void
    {
        echo static::class;
    }
    public function echoClassDynamic(): void
    {
        echo static::class;
    }
}
class B extends A{}
class C extends B{}

class D extends C{
    public static function echoClass(): void
    {
        // 静的メソッドの中の呼出しでは
        
        // parent を使うと親の static:: まで自分のクラスが伝播する
        parent::echoClass();// D
        // 親クラスを直に指定すると static:: で参照されるのは指定したクラス
        C::echoClass();// C
        B::echoClass();// B
    }

    public function echoClassDynamic(): void
    {
        // 動的メソッドの中の呼出しでは
        
        // どの場合でも自分のクラスが伝播する
        parent::echoClassDynamic();// D
        C::echoClassDynamic();// D
        B::echoClassDynamic();// D
    }
}

D::echoClass();
(new D)->echoClassDynamic();

 コメントにある通り、静的メソッドの中では呼び出し方でどのクラスがstatic::で参照されるクラスか変わります。これとクラス名を利用した機能が合わさると期待したクラス名が参照されずに期待しない挙動に繋がり問題が起きるということがあります。

 このクラスの参照の仕組みは遅延静的束縛として名づけられて次のページにあります。

PHP: 遅延静的束縛 (Late Static Bindings) – Manual

 中身はややこしいですがこの仕組みを端に発する問題に遭わない方法は親クラスを指定する時はparent::で指定する、というそれだけです。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG