
こんにちは。よっしーです(^^)
今日は、PHPのTraits(トレイト)についてご紹介します。
背景
PHP8.2を利用したAPIを開発しているときに Traits を利用したので、そのときの調査内容を備忘としてのこしました。
こちらのサイトを参考にしています。
メソッドの可視性の変更
as 構文を使用すると、表示クラス内のメソッドの可視性を調整することもできます。
<?php
trait HelloWorld {
public function sayHello() {
echo 'Hello World!';
}
}
// Change visibility of sayHello
class MyClass1 {
use HelloWorld { sayHello as protected; }
}
// Alias method with changed visibility
// sayHello visibility not changed
class MyClass2 {
use HelloWorld { sayHello as private myPrivateHello; }
}
?>
as構文を使用して、クラス内のメソッドの可視性を調整しています。それぞれのクラスで何が起こっているかを説明します。
MyClass1:
class MyClass1 {
use HelloWorld { sayHello as protected; }
}
MyClass1では、HelloWorldトレイトが使用され、トレイトからのsayHelloメソッドの可視性がprotectedに変更されています。つまり、MyClass1内のsayHelloメソッドはprotectedメソッドになります。MyClass1を拡張する他のクラスはこのメソッドにアクセスできますが、クラスの外部からは見えません。
MyClass2:
class MyClass2 {
use HelloWorld { sayHello as private myPrivateHello; }
}
MyClass2では、HelloWorldトレイトが使用され、トレイトからのsayHelloメソッドがprivate可視性でmyPrivateHelloとして別名付けされています。つまり、MyClass2にはmyPrivateHelloという名前のプライベートメソッドがあり、これはトレイトからのsayHelloメソッドの別名です。トレイト内の元のsayHelloメソッドの可視性は変更されません。それは引き続きパブリックです。
両方の場合、HelloWorldトレイトが使用され、トレイトのメソッドの可視性はas構文を使用して表示されるクラス内で調整されています。これにより、表示クラス内でメソッドの可視性を細かく制御できるようになります。
Traitsから構成されるTraits
クラスがTraitsを利用できるのと同じように、他のTraitsも利用できます。Traits定義で 1 つ以上のTraitsを使用すると、他のTraitsで定義されたメンバーの一部または全体をTraits定義で構成できます。
<?php
trait Hello {
public function sayHello() {
echo 'Hello ';
}
}
trait World {
public function sayWorld() {
echo 'World!';
}
}
trait HelloWorld {
use Hello, World;
}
class MyHelloWorld {
use HelloWorld;
}
$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
?>
Traits(トレイト)も他のトレイトから構成できます。 上記の例では、Hello と World という2つのトレイトがあり、それらを使用して新しいトレイト HelloWorld を作成します。最後に、MyHelloWorld クラスで HelloWorld トレイトを使用します。
以下はこの例の詳細です:
HelloトレイトはsayHelloというメソッドを定義し、”Hello ” を出力します。WorldトレイトはsayWorldというメソッドを定義し、”World!” を出力します。HelloWorldトレイトはHelloとWorldトレイトの両方を使用し、それらの動作を組み合わせます。MyHelloWorldクラスはHelloWorldトレイトを使用し、HelloとWorldトレイトからメソッドを継承および使用します。
MyHelloWorld のインスタンスを作成し、sayHello および sayWorld メソッドを呼び出すと、”Hello World!” という結果が得られます。これは、クラスがこれらのメソッドを提供するトレイトから構成されているためです。
これにより、コードのモジュール化と再利用が実現され、トレイトを組み合わせてクラス内でより複雑な動作を構築できます。
上記の例では次のように出力されます。
Hello World!
抽象メソッド
トレイト(Traits)は、要求をクラスに課すために抽象メソッドをサポートしています。これには、public、protected、privateなメソッドがサポートされており、PHP 8.0.0以前ではpublicとprotectedの抽象メソッドのみがサポートされていました。
以下の例では、抽象メソッドを使用して要求を表現しています:
trait Hello {
public function sayHelloWorld() {
echo 'Hello'.$this->getWorld();
}
abstract public function getWorld();
}
class MyHelloWorld {
private $world;
use Hello;
public function getWorld() {
return $this->world;
}
public function setWorld($val) {
$this->world = $val;
}
}
この例では、Hello トレイト内で getWorld という抽象メソッドが宣言されています。MyHelloWorld クラスが Hello トレイトを使用するためには、getWorld メソッドを実装しなければなりません。
MyHelloWorld クラスで getWorld メソッドが実装され、それによって要求された抽象メソッドを満たしています。このように、トレイト内の抽象メソッドを使用することで、クラスが必要なメソッドを実装することが保証されます。
おわりに
今日は、PHPのTraits(トレイト)についてご紹介しました。

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)



コメント