專案中全域變數泛濫污染命名空間,Zend_Registry 提供統一、型別安全的容器,儲存任意物件/值,避免 $GLOBALS 濫用。
Zend_Registry::set('config', $config); // 存入
$config = Zend_Registry::get('config'); // 取出
class Zend_Registry extends ArrayObject {
// ArrayObject 實現: IteratorAggregate, Traversable, ArrayAccess, Serializable, Countable
}
ArrayObject 使 Registry 具備陣列操作介面(offsetGet/Set/Unset/Exists)、可遍歷、可序列化、可計數。
public static function set($index, $value) {
$instance = self::getInstance(); // 靜態單例取得實例
$instance->offsetSet($index, $value); // ArrayObject 方法存入
}
public static function get($index) {
$instance = self::getInstance();
if (!$instance->offsetExists($index)) return null;
return $instance->offsetGet($index);
}
public static function getInstance() {
if (self::$_instance === null) {
self::$_instance = new self(); // 延遲實例化
}
return self::$_instance;
}
傳統單例需兩步:$a = A::getInstance(); $a->setVal();
Registry 簡化為一步:A::setVal(); —— 內部靜態方法自動 getInstance() 再委派實例方法。
class Registry {
private static $_instance;
private $_data = [];
private function __construct() {}
public static function getInstance() {
return self::$_instance ?? (self::$_instance = new self());
}
public static function set($key, $value) {
self::getInstance()->_data[$key] = $value;
}
public static function get($key) {
return self::getInstance()->_data[$key] ?? null;
}
}
// 使用
Registry::set('db', $pdo);
$db = Registry::get('db');
assert($obj instanceof PDO)。PHP-DI、Symfony DI、Laravel Container 更利於解耦與測試。