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中文網其他相關文章!

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

方法:1、用“str_replace(" ","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\ \;||\xc2\xa0)/","其他字符",$str)”语句。

在PHP中,可以利用implode()函数的第一个参数来设置没有分隔符,该函数的第一个参数用于规定数组元素之间放置的内容,默认是空字符串,也可将第一个参数设置为空,语法为“implode(数组)”或者“implode("",数组)”。

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載
最受歡迎的的開源編輯器