PHP 5/7/8 逐步完善了面向對象特性。本文梳理 16 個核心知識點,涵蓋類型系統、繼承機制、靜態成員、抽象與接口、異常處理、攔截器、生命周期、克隆、自動加載、反射等,適合進階學習與面試複習。
if ("false") // true!非空字符串均為 true
// 正確判斷布爾字符串:
$val = filter_var("false", FILTER_VALIDATE_BOOLEAN); // false
is_array(), is_object(), is_string(), is_null(), is_int(), is_float(), is_bool(), is_callable(), is_iterable()
function write(ShopProduct $product) {} // 僅限類/接口,不支援標量(PHP 7.0+ 支援標量提示)
// PHP 7.4+ 類型屬性
class Foo { public string $name; }
if ($obj instanceof BookProduct) {}
// 也可用於接口、父類判斷
class Child extends ParentClass {
public function __construct() {
parent::__construct(); // 必須顯式調用
}
}
class StaticExample {
public static string $name = 'PHP';
public static function hello(): string { return "Hello " . self::$name; }
}
// 外部訪問
echo StaticExample::$name;
echo StaticExample::hello();
// 內部訪問用 self:: 或 static::(晚靜態綁定)
abstract class BaseWriter {
abstract public function write(string $data): void; // 無方法體
public function save() { /* 通用邏輯 */ }
}
class JsonWriter extends BaseWriter {
public function write(string $data): void { /* 實現 */ }
}
子類實現的訪問權限不能比抽象方法更嚴格(如 abstract protected → 子類必須 protected/public)。
interface Loggable {
public function log(string $msg): void;
}
class FileLogger implements Loggable {
public function log(string $msg): void { /* 寫文件 */ }
}
// 一個類可 implements 多個接口
try {
risky();
} catch (SpecificException $e) {
// 處理特定異常
} catch (Throwable $e) { // PHP 7+ 統一捕獲 Exception & Error
// 記錄日誌
throw $e; // 重新拋出
} finally {
// 清理資源
}
| 方法 | 觸發時機 |
|---|---|
| __get($name) | 讀取不可訪問/不存在屬性 |
| __set($name, $value) | 寫入不可訪問/不存在屬性 |
| __isset($name) | isset() 檢查不可訪問屬性 |
| __unset($name) | unset() 不可訪問屬性 |
| __call($name, $args) | 調用不可訪問/不存在方法 |
| __callStatic($name, $args) | 靜態調用不存在方法 |
典型應用:動態屬性代理、只讀屬性、方法分發。
對象銷毀前自動調用,用於釋放資源(關閉連接、寫入緩存)。注意:腳本結束時不保證調用順序,不要在析構函數中依賴其他對象。
$obj2 = clone $obj1; // 淺拷貝
// 若需深拷貝,實現 __clone() 手動 clone 內部對象屬性
PHP 5+ 對象賦值/傳參默認引用,clone 產生獨立副本。
// 老式(已棄用)
function __autoload($class) { include "$class.php"; }
// 現代標準:PSR-4 + Composer 自動加載
// composer.json: "autoload": { "psr-4": { "App\\": "src/" } }
// 運行 composer dump-autoload 生成 vendor/autoload.php
require __DIR__ . '/vendor/autoload.php'; // 一行搞定所有類加載
$class = 'Task';
$method = 'getTitle';
$obj = new $class();
$obj->$method(); // 可讀性較差,慎用
class_exists('Foo');
get_declared_classes();
get_class_methods($objOrClass);
method_exists($obj, 'method');
is_callable([$obj, 'method']);
get_class_vars('Foo');
get_parent_class($obj);
is_subclass_of($obj, 'Base');
$ref = new ReflectionClass('SomeClass');
$props = $ref->getProperties();
$methods = $ref->getMethods();
$constructor = $ref->getConstructor();
$instance = $ref->newInstanceArgs($args); // 動態實例化
// 可獲取註解、修飾符、參數類型等元數據
match、attributes、constructor promotion、union types、named arguments,極大增強 OOP 表達力。declare(strict_types=1); 強制類型檢查,建議所有新項目開啟。