tohokuaikiのチラシの裏

技術的ネタとか。

traitのメソッドをoverwriteしたんだけど、そのoverwriteされたメソッドを呼びたい場合

参考にさせていただきました

qiita.com ありがとうございました。

試行錯誤してみる

まずは基本となるtraitのAと親クラスBaseを定義

<?php
trait A
{
    public function say()
    {
        echo "I am A\n";
    }
}

class Base
{
    public function say()
    {
        echo "I am Base\n";
    }
}

で、Baseを継承しAをtraitしたクラスを作る

<?php
class Sayer extends Base
{
    use A ;

    public function say()
    {
        echo "I am Sayer\n";
    }
}

このSayerクラスのsay()メソッドからtraitのsay()メソッドをコールしたいわけです。

単純にparentを使った

<?php
class Sayer extends Base
{
    use A ;

    public function say()
    {
        echo "I am Sayer\n";
        parent::say();
        $this->sayA();
    }
}

(new Sayer())->say();

結果

I am Sayer
I am Base

そりゃー、そーですよね。parentは継承元のクラスなんで…

単純に$this->を使った

<?php
class Sayer extends Base
{
    use A;
    
    public function say()
    {
        echo "I am Sayer\n";
        $this->say();
    }
}
(new Sayer())->say();

結果

I am Sayer
I am Sayer
...(略:252回繰り返す)
I am Sayer
I am Sayer
PHP Fatal error:  Uncaught Error: Maximum function nesting level of '256' reached, aborting! in /home/vagrant/work/trait_parent.php:22

メソッドループして怒られた。…当たり前だな。

解決方法

use ... as を使う

<?php
class Sayer extends Base
{
    use A {
        A::say as sayA;
    }
    
    public function say()
    {
        echo "I am Sayer\n";
        $this->sayA();
    }
}
(new Sayer())->say();

結果

I am Sayer
I am A

無事traitのメソッドが呼び出せた。