[ PHP ] マジックメソッド __call ( 存在しないメソッド、private、protected メソッドを呼び出す )

Pocket

マジックメソッド ( __call ) を使用することで定義していないメドッソでも処理することができるようになります。また、private メソッド や protected メソッドを間接的に呼び出すことができるようになります。

private メソッドの呼び出しは PHP 5.3 以降からできるようになっています。

参考:PHP マニュアル:PHP 5.2.x から PHP 5.3.x への移行 下位互換性のない変更点

スポンサーリンク

マジックメソッド __call のサンプルスクリプト

存在しないメソッドや、private、protected メソッドを外部から呼び出すサンプルコードです。サンプル内のコメントも参照ください。

class callClass
{
    /*
     * __call マジックメソッド
     */
    public function __call($name, $args)
    {
        if($name == 'publicFuncAlias') {
        
            // public メソッドの呼び出し
            $this->publicFunc($args);
            
        } else {
        
            // 存在しないメソッド名の場合はリターン
            if(!method_exists($this, $name)) { return false; }

            // クラス内 private / protected メソッドの呼び出し
            $this->{$name}($args);
            
        }
    }

    /*
     * public メソッド
     *
     * [メモ]
     * publicFunc はマジックメソッド経由だけでなく、直接呼び出されることもあるので
     * デフォルトパラメータを付けておかないと、以下のような、警告が出力される
     * Warning: Missing argument 1 for callClass::publicFunc(), called in ・・・
     */
    public function publicFunc($args = null)
    {
        echo "I am public method\n";
    }

    /*
     * protected メソッド
     */
    protected function protectedFunc($args)
    {
        echo "I am protected method\n";
    }

    /*
     * private メソッド
     */
    private function privateFunc($args)
    {
        echo "I am private method\n";
    }
}

$call = new callClass();

$call->publicFuncAlias(); // public    メソッドをマジックメソッド経由で呼び出す
$call->protectedFunc();   // protected メソッドをマジックメソッド経由で呼び出す
$call->privateFunc();     // private   メソッドをマジックメソッド経由で呼び出す


// 動作結果
// ----------------------------------------------------------------
// I am public method
// I am protected method
// I am private method
//

// (参考)仕様変更前の動作結果
// ----------------------------------------------------------------
// PHP Fatal error:  Call to protected method callClass::protectedFunc() from context in ・・
// PHP Fatal error:  Call to private method callClass::privateFunc() from context in ・・
//

メモ

上記のサンプルコードでは、存在しないメソッド名の場合はリターンさせています。この処理がないと、存在しないメソッドを呼び出した場合に無限ループが発生して、以下のようにエラーとなります。

Fatal error: Maximum function nesting level of ‘100’ reached, aborting! in ・・・

スポンサーリンク


Pocket

Leave a Comment

Your email address will not be published. Required fields are marked *