<?php
trait ReusableTrait
{
public const VERSION = '1.0';
public function sha256(string $data): string
{
return hash('sha256', $data);
}
public function log(string $msg): void
{
$time = date('c');
echo "[{$time}] $msg" . PHP_EOL;
}
}
/* ────────── 兩個會衝突的 Trait ────────── */
trait GreetingATrait
{
public function sayHello(): string
{
return 'Hello from A';
}
}
trait GreetingBTrait
{
public function sayHello(): string
{
return 'Hello from B';
}
}
/* ────────── 抽象類別 ────────── */
abstract class Person
{
protected string $name;
public function __construct(string $name)
{
$this->name = $name;
}
/* 抽象方法:子類必須實作 */
abstract public function getId(): int;
}
/* ────────── 兩個同用 ReusableTrait 的類別 ────────── */
class User extends Person
{
use ReusableTrait;
private int $id;
public function __construct(string $name, int $id)
{
parent::__construct($name);
$this->id = $id;
}
public function getId(): int
{
return $this->id;
}
public function save(): void
{
/* 同時使用 Trait 的雜湊與日誌功能 */
$digest = $this->sha256($this->name);
$this->log("User {$this->name} saved. digest={$digest}");
}
}
class Admin extends Person
{
use ReusableTrait;
private int $level;
public function __construct(string $name, int $level)
{
parent::__construct($name);
$this->level = $level;
}
public function getId(): int
{
// 以權限等級產生一個簡易 ID
return $this->level * 100;
}
}
/* ────────── 同時 use 兩個有同名方法的 Trait ────────── */
class Robot extends Person
{
use GreetingATrait, GreetingBTrait {
GreetingBTrait::sayHello insteadof GreetingATrait; // 指定以 B 版本為主
GreetingATrait::sayHello as sayHelloFromA; // 另取別名保留 A 版本
}
public function getId(): int
{
return 0; // 機器人固定回傳 0
}
}
$u = new User('Alice', 1);
$u->save();
$a = new Admin('Bob', 3);
$a->log('Admin logged in.');
$r = new Robot('R2-D2');
echo $r->sayHello(); // 來自 GreetingBTrait → Hello from B
echo PHP_EOL;
echo $r->sayHelloFromA(); // 來自 GreetingATrait → Hello from A
echo PHP_EOL;