PHP 5 重寫核心 (Zend Engine 2),引入完整物件模型,從「基於對象的腳本」邁向「面向對象語言」。本文系統梳理六大核心特性。
<?php
abstract class Shape {
protected $color;
abstract public function getArea(); // 無方法體,分號結束
public function setColor($c) { $this->color = $c; }
}
class Circle extends Shape {
private $radius;
public function __construct($r) { $this->radius = $r; }
public function getArea() { // 必須實現
return M_PI * $this->radius ** 2;
}
}
$c = new Circle(5);
echo $c->getArea(); // 78.54...
?>
<?php
class Magic {
public function __call($name, $args) {
if ($name === '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 $name not found");
}
private function fooInt($x) { echo "int: $x\n"; }
private function fooStr($s) { echo "str: $s\n"; }
}
$m = new Magic();
$m->foo(123); // int: 123
$m->foo('abc'); // str: abc
?>
實現「方法重載」:根據參數類型/數量分派不同邏輯。
<?php
class Entity {
private $data = [];
public function __set($name, $val) { $this->data[$name] = $val; }
public function __get($name) { return $this->data[$name] ?? null; }
}
$e = new Entity();
$e->name = 'Tom'; // 觸發 __set
echo $e->name; // 觸發 __get
echo $e->age; // null (不報錯)
?>
應用:動態屬性、ORM 實體、數據代理、懶加載。
<?php
class Logger { public function log($msg) { echo $msg; } }
class Service {
// 參數必須是 Logger 實例
public function setLogger(Logger $logger) {
$this->logger = $logger;
}
}
$svc = new Service();
$svc->setLogger(new Logger()); // OK
$svc->setLogger('string'); // Catchable fatal error
?>
<?php
class Math {
public static $PI = 3.1415926;
public static function add($a, $b) { return $a + $b; }
}
echo Math::$PI; // 3.1415926
echo Math::add(3, 7); // 10
// 無需實例化
?>
<?php
class DivideByZeroException extends Exception {}
class Calculator {
public function div($a, $b) {
if ($b == 0) throw new DivideByZeroException('除數不能為零');
return $a / $b;
}
}
try {
$calc = new Calculator();
echo $calc->div(10, 0);
} catch (DivideByZeroException $e) {
echo '業務異常: ' . $e->getMessage();
} catch (Exception $e) {
echo '系統異常: ' . $e->getMessage();
} finally {
echo ' -- 清理資源 --';
}
?>
<?php
namespace Math\Geometry;
class Circle {
public function area($r) { return M_PI * $r * $r; }
}
// 使用
$c = new \Math\Geometry\Circle();
// 或
use Math\Geometry\Circle;
$c = new Circle();
?>
| 特性 | 意義 |
|---|---|
| 抽象類/接口 | 契約導向設計、依賴倒置基石 |
| 魔術方法 | 元編程、動態代理、DSL 構建 |
| 類型提示 | 契約檢查、IDE 智能提示、重構安全 |
| 靜態成員 | 工具類、單例、註冊表模式 |
| 異常處理 | 錯誤與業務邏輯分離、棧追蹤、資源安全 |
| 命名空間 | 大型項目模組化、生態互操作 |