PHP 不支援方法重載,無法直接定義多個 __construct。需通過參數檢測分發到不同內部構建方法。
__construct(...$args) 接收所有參數。string、int、DateTime、array)。construct_類型1_類型2... 方法。<?php
class ClassUtil {
public static function typeOf(mixed $var): string {
if (is_object($var)) return get_class($var);
if (is_array($var)) return 'array';
if (is_numeric($var)) return 'numeric';
if (is_bool($var)) return 'bool';
if (is_null($var)) return 'null';
return 'string';
}
public static function typeList(array $args): array {
return array_map([self::class, 'typeOf'], $args);
}
public static function callMethodForArgs(object $obj, array $args, string $prefix = 'construct'): void {
$method = $prefix . '_' . implode('_', self::typeList($args));
if (!is_callable([$obj, $method])) {
throw new BadMethodCallException(
"Class " . get_class($obj) . " has no method '$method' for args (" .
implode(', ', self::typeList($args)) . ")"
);
}
call_user_func_array([$obj, $method], $args);
}
}
class DateTimeEx {
private int $timestamp;
public function __construct(...$args) {
ClassUtil::callMethodForArgs($this, $args);
}
// 空參數 → 當前時間
public function construct_() { $this->timestamp = time(); }
// 接收 DateTimeEx 實例
public function construct_DateTimeEx(DateTimeEx $dt) { $this->timestamp = $dt->getTimestamp(); }
// 接收 Unix 時間戳
public function construct_numeric(int $ts) { $this->timestamp = $ts; }
// 接收日期字符串
public function construct_string(string $str) { $this->timestamp = strtotime($str); }
// 接收 DateTime 內建類
public function construct_DateTime(DateTime $dt) { $this->timestamp = $dt->getTimestamp(); }
public function getTimestamp(): int { return $this->timestamp; }
public function format(string $fmt): string { return date($fmt, $this->timestamp); }
}
// 使用示例
$d1 = new DateTimeEx(); // 當前時間
$d2 = new DateTimeEx(1705312200); // 時間戳
$d3 = new DateTimeEx('2024-01-15 14:30'); // 字符串
$d4 = new DateTimeEx(new DateTime()); // DateTime 對象
$d5 = new DateTimeEx(new DateTimeEx()); // 自身對象
echo $d3->format('Y-m-d H:i:s'); // 2024-01-15 14:30:00
ReflectionMethod 緩存方法查找,提升性能。construct_string_numeric 匹配 (string, int)。DateTimeEx::createFromString() 等靜態工廠更語義化。if/else 或 switch 判斷參數類型。