Heim > Backend-Entwicklung > PHP-Tutorial > So überwinden Sie die Namensbeschränkungen von PHP zur Modellierung von MongoDB-Operatoren

So überwinden Sie die Namensbeschränkungen von PHP zur Modellierung von MongoDB-Operatoren

DDD
Freigeben: 2023-10-18 10:58:01
nach vorne
805 Leute haben es durchsucht

MongoDB bietet Treiber für verschiedene Sprachen, einschließlich PHP. Um den Prozess der Erstellung von Aggregationspipelines in PHP zu vereinfachen, müssen wir alle Phasen und Operatoren als zusammensetzbare Funktionen modellieren.

Aggregationspipeline ist eine Liste von „Stufen“-Dokumenten. Wir geben ein Beispiel für die Abfrage von $match und die Verknüpfung mit $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"
        }
    }
])
Nach dem Login kopieren

Jeder Schlüssel mit einem Dollar-Präfix ist ein Operator, für den wir eine Factory-Methode bereitstellen möchten.

Namespace-Funktionen

Die naheliegendste Lösung besteht darin, eine Namespace-Funktion zu erstellen, zum Beispiel: MongoDBOperatoreqof$eq-Operator.

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,
    ]];
}
Nach dem Login kopieren

Bei Verwendung von Funktionen mit benannten Parametern werden Pipes in PHP geschrieben:

pipeline(
    match(
        or(
            query(status: eq('shipped')),
            query(date: gte(new UTCDateTime())),
        ),
    ),
    lookup(from: 'inventory', localField: 'product_id', foreignField: 'product_id', as: 'inventory_docs'),
);
Nach dem Login kopieren

Allerdings stehen einige Operatornamen im Konflikt mit reservierten Schlüsselwörtern in PHP. Wir können keine Funktionen (global oder Namespace) mit den folgenden Namen erstellen:

and,

or,

match,

unset,

set,

Suffix zum Funktionsnamen hinzufügen

Um das Problem der Namensspeicherung zu vermeiden, können wir dem Funktionsnamen ein Präfix oder Suffix hinzufügen.

Mit dem Operatortyp angehängt:

function andQuery(...) { /* ... */ }
function matchStage(...) { /* ... */ }
Nach dem Login kopieren

Unterstrichen:

function _and(...) { /* ... */ }
function _match(...) { /* ... */ }
Nach dem Login kopieren

Oder verwenden Sie Emoticons. Schön, aber unpraktisch:

function ?and(...) { /* ... */ }
function ?match(...) { /* ... */ }
Nach dem Login kopieren

Statische Klassenmethode

Zufällig ist die Liste der reservierten Schlüsselwörter für Methodennamen kürzer. Wir können statische Methoden für Klassen erstellen.

final class Stage {
    public static function lookup(...) { /* ... */ }
    public static function match(...) { /* ... */ }
}
final class Query {
    public static function and(...) { /* ... */ }
    public static function eq(...) { /* ... */ }
}
Nach dem Login kopieren

Der Text ist etwas lang, aber dennoch lesbar.

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'),
);
Nach dem Login kopieren

Um zu verhindern, dass jemand eine Instanz dieser Klasse erstellt, können wir den Konstruktor privat machen.

final class Operator {
    // ...
    private function __construct() {} // This constructor cannot be called 
}
Nach dem Login kopieren

Wir können enum auch ohne Shell verwenden. Enum akzeptiert statische Methoden und kann nicht instanziiert werden.

enum Query {
    public static function and() { /* ... */ }
    public static function eq() { /* ... */ }
}
Nach dem Login kopieren

Statische Klassen- und Aufzählungsmethoden können auf die gleiche Weise aufgerufen werden.

Abschlüsse in Variablen

Da wir keine ideale Lösung finden konnten, begannen wir, uns für unwahrscheinliche Lösungen zu begeistern.

Wenn wir eine kurze Syntax wünschen, die der MongoDB-Syntax ohne Namensbeschränkungen sehr ähnlich sieht, dann würden wir über die Verwendung von Variablen zum Speichern von Abschlüssen nachdenken. Beachten Sie, dass dies (...) die neue Syntax zum Erstellen von Abschlüssen in PHP 8.1 ist.

$eq = Operator::eq(...);
$and = Operator::and(...);
Nach dem Login kopieren

$PHP verwendet ein Dollarzeichen für variable Präfixe und MongoDB verwendet denselben Operator für Präfixe.

pipeline(
    $match(
        $or(
            $query(status: $eq('shipped')),
            $query(date: $gte(new UTCDateTime())),
        ),
    ),
    $lookup(from: 'inventory', localField: 'product_id', foreignField: 'product_id', as: 'inventory_docs'),
);
Nach dem Login kopieren

Die Bibliothek kann diese Abschlüsse als Arrays bereitstellen.

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(...),
        ];
    }
}
Nach dem Login kopieren

Die Syntax zum Abrufen aller Variablen ist etwas ausführlich, aber dennoch lesbar.

['and' => $and, 'eq' => $eq, 'query' => $query] = Query::functions();
Nach dem Login kopieren

extrahieren Wir können alle Variablen in den aktuellen Bereich importieren, indem wir eine magische Funktion in Laravel verwenden, die oft verwendet wird, aber von PHPStorm und statischen Analysetools gehasst wird.

extract(Query::functions());
var_dump($and(
    $query(foo: $eq(5)),
    $query(bar: $eq(10))
));
// INFO: MixedFunctionCall - Cannot call function on mixed
Nach dem Login kopieren

Fazit

Wie Sie sehen, ist die Benennung von Funktionen in PHP nicht so einfach, wenn reservierte Schlüsselwörter verwendet werden.

Das obige ist der detaillierte Inhalt vonSo überwinden Sie die Namensbeschränkungen von PHP zur Modellierung von MongoDB-Operatoren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:Jérôme TAMARELLE
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage