こんにちは。よっしーです(^^)
今日は、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(トレイト)についてご紹介しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント