如何克服PHP的命名限制來建模MongoDB運算符
MongoDB 提供了包括 PHP 在內的各種語言的驅動程式。為了簡化在 PHP 中建立聚合管道的過程,我們需要將所有階段和運算子建模為可以組合的函數。
聚合管道是「階段」文件的清單。我們將舉一個使用 進行查詢$match和連接的範例$lookup:
db.orders.aggregate([ { $match: { $or: [ { status: "shipped" }, { created_at: { $gte: ISODate("2023-01-01T00:00:00Z") } } ] } }, { $lookup: { from: "inventory", localField: "product_id", foreignField: "product_id", as: "inventory_docs" } } ])
每個帶有美元前綴的鍵都是我們要為其提供工廠方法的運算符。
命名空間函數
最明顯的解決方案是建立命名空間函數,例如:MongoDBOperatoreqof$eq運算子。
namespace MongoDB\Operator; function eq(mixed $value): array { return ['$eq' => $value]; } function lookup(string $from, string $localField, string $foreignField, string $as): array { return ['$lookup' => [ 'from' => $from, 'localField' => $localField, 'foreignField' => $foreignField, 'as' => $as, ]]; }
使用帶有命名參數的函數,管道將用 PHP 編寫:
pipeline( match( or( query(status: eq('shipped')), query(date: gte(new UTCDateTime())), ), ), lookup(from: 'inventory', localField: 'product_id', foreignField: 'product_id', as: 'inventory_docs'), );
但是,某些運算符名稱與PHP 中的保留關鍵字衝突。我們無法建立具有以下名稱的函數(全域或命名空間):
and,
or,
match,
unset,
set,
為函數名稱加上字尾
為了避免保留名稱的問題,我們可以在函數名稱中加上前綴或後綴。
以運算符類型作為後綴:
function andQuery(...) { /* ... */ } function matchStage(...) { /* ... */ }
帶下劃線:
function _and(...) { /* ... */ } function _match(...) { /* ... */ }
或使用表情符號。漂亮,但不實用:
function ?and(...) { /* ... */ } function ?match(...) { /* ... */ }
靜態類別方法
碰巧的是,方法名稱的保留關鍵字清單較短。我們可以在類別上建立靜態方法。
final class Stage { public static function lookup(...) { /* ... */ } public static function match(...) { /* ... */ } } final class Query { public static function and(...) { /* ... */ } public static function eq(...) { /* ... */ } }
字寫得有點長了,不過還是可讀的。
new Pipeline( Stage::match( Query::or( Query::query(status: Query::eq('shipped')), Query::query(date: Query::gte(new UTCDateTime())), ), ), Stage::lookup(from: 'inventory', localField: 'product_id', foreignField: 'product_id', as: 'inventory_docs'), );
為了防止任何人建立此類別的實例,我們可以將建構函式設為私有。
final class Operator { // ... private function __construct() {} // This constructor cannot be called }
我們也可以使用enum不含外殼的。 Enum 接受靜態方法且不能實例化。
enum Query { public static function and() { /* ... */ } public static function eq() { /* ... */ } }
類別和枚舉靜態方法都可以以相同的方式呼叫。
變數中的閉包
由於找不到理想的解決方案,我們開始熱衷於不太可能的解決方案。
如果我們想要一個看起來與 MongoDB 語法非常相似且沒有名稱限制的簡短語法,那麼我們就會想到使用變數來儲存閉包。請注意,這(...)是PHP 8.1 中建立閉包的新語法。
$eq = Operator::eq(...); $and = Operator::and(...);
$PHP 使用美元符號作為變數前綴,MongoDB 使用相同的運算子作為前綴。
pipeline( $match( $or( $query(status: $eq('shipped')), $query(date: $gte(new UTCDateTime())), ), ), $lookup(from: 'inventory', localField: 'product_id', foreignField: 'product_id', as: 'inventory_docs'), );
函式庫可以將這些閉包作為陣列提供。
enum Query { public static function and(array ...$queries) { /* ... */ } public static function eq(mixed $value) { /* ... */ } public static function query(mixed ...$query) { /* ... */ } /** @return array{and:callable,eq:callable,query:callable} */ public static function functions(): array { return [ 'and' => self::and(...), 'eq' => self::eq(...), 'query' => self::query(...), ]; } }
取得所有變數的語法有點冗長,但仍可讀。
['and' => $and, 'eq' => $eq, 'query' => $query] = Query::functions();
extract我們可以使用 Laravel 中經常使用但 PHPStorm 和靜態分析工具非常討厭的神奇功能將所有變數導入到當前作用域中。
extract(Query::functions()); var_dump($and( $query(foo: $eq(5)), $query(bar: $eq(10)) )); // INFO: MixedFunctionCall - Cannot call function on mixed
結論
正如您所看到的,在使用保留關鍵字時,PHP 中的函數命名並不那麼簡單。
以上是如何克服PHP的命名限制來建模MongoDB運算符的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

在PHP8 中,match表達式是一種新的控制結構,用於根據表達式的值返回不同的結果。 1)它類似於switch語句,但返回值而非執行語句塊。 2)match表達式使用嚴格比較(===),提升了安全性。 3)它避免了switch語句中可能的break遺漏問題,增強了代碼的簡潔性和可讀性。

在PHP中可以通過使用不可預測的令牌來有效防範CSRF攻擊。具體方法包括:1.生成並在表單中嵌入CSRF令牌;2.在處理請求時驗證令牌的有效性。

在PHP中,final關鍵字用於防止類被繼承和方法被重寫。 1)標記類為final時,該類不能被繼承。 2)標記方法為final時,該方法不能被子類重寫。使用final關鍵字可以確保代碼的穩定性和安全性。

PHP中的...(splat)操作符用於函數參數和數組解包,提升代碼簡潔性和效率。 1)函數參數解包:將數組元素作為參數傳遞給函數。 2)數組解包:將一個數組解包到另一個數組中或作為函數參數。

PHP中的嚴格類型通過在文件頂部添加declare(strict_types=1);來啟用。 1)它強制對函數參數和返回值進行類型檢查,防止隱式類型轉換。 2)使用嚴格類型可以提高代碼的可靠性和可預測性,減少bug,提升可維護性和可讀性。

Composer是PHP的依賴管理工具。使用Composer的核心步驟包括:1)在composer.json中聲明依賴,如"stripe/stripe-php":"^7.0";2)運行composerinstall下載並配置依賴;3)通過composer.lock和autoload.php管理版本和自動加載。 Composer簡化了依賴管理,提升了項目效率和可維護性。

PHP的未來將通過適應新技術趨勢和引入創新特性來實現:1)適應云計算、容器化和微服務架構,支持Docker和Kubernetes;2)引入JIT編譯器和枚舉類型,提升性能和數據處理效率;3)持續優化性能和推廣最佳實踐。
