PHP 5 (2004 年釋出) 是 PHP 歷史上最大規模的核心重寫,Zend Engine 2 引入完整物件模型,奠定現代 PHP 框架(Laravel、Symfony 等)的基礎。本文回顧 PHP 5 初期三大里程碑特性:**新物件模型、例外處理、命名空間**(註:命名空間實際於 PHP 5.3 才釋出,但設計討論始於 PHP 5 早期)。
class Foo {
public $x;
public function __construct($x) { $this->x = $x; } // 統一命名
public function __destruct() { echo "bye bye"; } // 新增:物件銷毀時自動呼叫
}
$o = new Foo(4);
$o->display(); // 輸出 4
// 腳本結束或 unset($o) 時輸出 "bye bye"
class Foo { public $x; function setX($v){$this->x=$v;} function getX(){return $this->x;} }
$o1 = new Foo; $o1->setX(4);
$o2 = $o1; // PHP 5:$o2 參考同一物件實例
$o1->setX(5);
echo $o2->getX(); // 輸出 5(PHP 4 輸出 4,因為複製)
**影響**:不再需要到處加 `&` 參考符號,物件行為符合直覺與 Java/C# 一致。
$o1 = new Foo; $o1->setX(4);
$o2 = clone $o1; // 關鍵字 clone,觸發 __clone()
$o1->setX(5);
echo $o1->getX(); // 5
echo $o2->getX(); // 4(獨立副本)
可在 `__clone()` 中自訂深層複製邏輯(如複製關聯物件)。
class Base {
private $secret = 'base';
protected $shared = 'shared';
public $open = 'open';
private function onlyBase() { echo "base only"; }
protected function baseAndChild() { echo "base+child"; }
public function anyone() { echo "anyone"; }
}
class Child extends Base {
public function test() {
$this->anyone(); // OK
$this->baseAndChild(); // OK
// $this->onlyBase(); // Fatal: private 僅基底類別可存取
echo $this->shared; // OK
// echo $this->secret; // Fatal: private
}
}
$c = new Child;
$c->anyone(); // OK
$c->test();
// $c->baseAndChild(); // Fatal: protected
// $c->onlyBase(); // Fatal: private
**最佳實踐**:屬性預設 `private`,透過 `getter/setter` 控制存取;`protected` 供繼承體系共享;`public` 僅用於介面契約。
interface Displayable { public function display(); }
interface Printable { public function print(); }
abstract class BaseReport {
protected $data;
abstract public function render(); // 強制子類實作
public function setData($d) { $this->data = $d; }
}
class PdfReport extends BaseReport implements Displayable, Printable {
public function render() { /* PDF 邏輯 */ }
public function display() { echo "顯示 PDF"; }
public function print() { echo "列印 PDF"; }
}
class Magic {
private $data = [];
public function __call($method, $args) {
if ($method === 'foo') {
if (is_int($args[0])) return $this->fooInt($args[0]);
if (is_string($args[0])) return $this->fooStr($args[0]);
}
throw new BadMethodCallException("Method $method not found");
}
private function fooInt($x) { echo "int: $x"; }
private function fooStr($s) { echo "str: $s"; }
}
$m = new Magic;
$m->foo(123); // 輸出 int: 123
$m->foo('abc'); // 輸出 str: abc
實現**多載**與**動態屬性/方法**攔截,極大增強 DSL、Proxy、ORM 基礎設施能力。
class Processor {
public function process(Foo $foo) { /* $foo 必須為 Foo 實例 */ }
}
$p = new Processor;
$p->process(new Foo); // OK
// $p->process("string"); // Fatal: Argument must be instance of Foo
PHP 7+ 擴充為標量型別提示(`int`、`string`、`bool`、`float`)與回傳型別聲明。
class Calculator {
public static $PI = 3.1415926;
public static function add($a, $b) { return $a + $b; }
}
echo Calculator::$PI; // 3.1415926
echo Calculator::add(3, 7); // 10
// 無需實例化即可呼叫
class Divider {
public function divide($x, $y) {
if ($y == 0) throw new Exception("Division by zero");
return $x / $y;
}
}
try {
$d = new Divider;
echo $d->divide(10, 0);
} catch (Exception $e) {
echo "捕獲錯誤: " . $e->getMessage(); // 輸出: 捕獲錯誤: Division by zero
// 記錄日誌、發送告警、回傳友善錯誤頁面
} finally { // PHP 5.5+
echo "清理資源";
}
class AppException extends Exception {
protected $code;
public function __construct($message, $code = 0, Exception $previous = null) {
parent::__construct($message, $code, $previous);
$this->code = $code;
}
}
class ValidationException extends AppException {}
class DatabaseException extends AppException {}
try {
// ...
} catch (ValidationException $e) {
http_response_code(400);
echo json_encode(['error' => $e->getMessage()]);
} catch (DatabaseException $e) {
http_response_code(500);
error_log($e->getMessage());
echo "系統維護中";
}
**優勢**:錯誤處理與業務邏輯分離、支援多層捕獲、堆疊追蹤自動保留、利於單元測試。
namespace MyApp\Database;
class Connection { /* ... */ }
namespace MyApp\Cache;
class Connection { /* ... */ } // 同名類別,不同命名空間,互不干擾
// 使用
use MyApp\Database\Connection as DbConn;
use MyApp\Cache\Connection as CacheConn;
$db = new DbConn;
$cache = new CacheConn;
// composer.json
{
"autoload": {
"psr-4": {
"MyApp\\": "src/"
}
}
}
// src/Database/Connection.php → namespace MyApp\Database;
// src/Cache/Connection.php → namespace MyApp\Cache;
配合 Composer 自動載入,徹底解決 `require_once` 地獄,構建現代 PHP 生態基石。
| 特性 | PHP 4 | PHP 5 | 現代 PHP (7/8) |
|---|---|---|---|
| 物件傳遞 | 值複製 | 參考 | 參考 + 型別系統 |
| 建構/解構 | 同名函式 / 無 | __construct / __destruct | 同上 + 升級/降級建構子 |
| 可見度 | 全 public | public/protected/private | + readonly (8.1) |
| 錯誤處理 | trigger_error / die | try/catch/throw Exception | + Throwable / Error / finally / union types |
| 命名空間 | 無 | 5.3 引入 | PSR-4 / group use / 保留字解除 |
PHP 5 的三大支柱——**物件模型重構、例外處理、命名空間**——將 PHP 從「模板引擎」昇華為「通用物件導向程式語言」。現代 PHP 8.x 在此基礎上疊加 JIT、屬性、聯合型別、模式匹配等特性,但核心哲學一脈相承。理解 PHP 5 的設計初衷與演進邏輯,是掌握現代 PHP 架構思維的鑰匙。