Home Backend Development PHP Tutorial How to overcome PHP's naming limitations to model MongoDB operators

How to overcome PHP's naming limitations to model MongoDB operators

Oct 18, 2023 am 10:56 AM
php mongodb

MongoDB provides drivers for various languages ​​including PHP. To simplify the process of creating aggregation pipelines in PHP, we need to model all stages and operators as functions that can be composed.

Aggregation pipeline is a list of "stage" documents. We'll give an example of querying $match and joining using $lookup:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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"

        }

    }

])

Copy after login

Each key with a dollar prefix is ​​an operator for which we want to provide a factory method.

Namespace functions

The most obvious solution is to create a namespace function, for example: MongoDBOperatoreqof$eq operator.

1

2

3

4

5

6

7

8

9

10

11

12

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,

    ]];

}

Copy after login

Using functions with named parameters, pipes will be written in PHP:

1

2

3

4

5

6

7

8

9

pipeline(

    match(

        or(

            query(status: eq('shipped')),

            query(date: gte(new UTCDateTime())),

        ),

    ),

    lookup(from: 'inventory', localField: 'product_id', foreignField: 'product_id', as: 'inventory_docs'),

);

Copy after login

However, some operator names conflict with reserved keywords in PHP. We cannot create functions (global or namespace) with the following names:

and,

or,

match,

unset,

set,

Add suffix to function name

To avoid the problem of name retention, we can add prefix or suffix to function name.

Suffixed with operator type:

1

2

function andQuery(...) { /* ... */ }

function matchStage(...) { /* ... */ }

Copy after login

Underlined:

1

2

function _and(...) { /* ... */ }

function _match(...) { /* ... */ }

Copy after login

Or use emoticons. Pretty, but impractical:

1

2

function ?and(...) { /* ... */ }

function ?match(...) { /* ... */ }

Copy after login

Static class method

As it happens, the list of reserved keywords for method names is shorter. We can create static methods on classes.

1

2

3

4

5

6

7

8

final class Stage {

    public static function lookup(...) { /* ... */ }

    public static function match(...) { /* ... */ }

}

final class Query {

    public static function and(...) { /* ... */ }

    public static function eq(...) { /* ... */ }

}

Copy after login

The writing is a bit long, but it’s still readable.

1

2

3

4

5

6

7

8

9

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'),

);

Copy after login

To prevent anyone from creating an instance of this class, we can make the constructor private.

1

2

3

4

final class Operator {

    // ...

    private function __construct() {} // This constructor cannot be called

}

Copy after login

We can also use enum without shell. Enum accepts static methods and cannot be instantiated.

1

2

3

4

enum Query {

    public static function and() { /* ... */ }

    public static function eq() { /* ... */ }

}

Copy after login

Both class and enumeration static methods can be called in the same way.

Closures in variables

Since we couldn’t find an ideal solution, we started to get enthusiastic about unlikely solutions.

If we want a short syntax that looks very similar to MongoDB syntax without name restrictions, then we would think of using variables to store closures. Note that this (...) is the new syntax for creating closures in PHP 8.1.

1

2

$eq = Operator::eq(...);

$and = Operator::and(...);

Copy after login

$PHP uses a dollar sign for variable prefixes and MongoDB uses the same operator for prefixes.

1

2

3

4

5

6

7

8

9

pipeline(

    $match(

        $or(

            $query(status: $eq('shipped')),

            $query(date: $gte(new UTCDateTime())),

        ),

    ),

    $lookup(from: 'inventory', localField: 'product_id', foreignField: 'product_id', as: 'inventory_docs'),

);

Copy after login

The library can provide these closures as arrays.

1

2

3

4

5

6

7

8

9

10

11

12

13

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(...),

        ];

    }

}

Copy after login

The syntax for getting all variables is a bit verbose, but still readable.

1

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

Copy after login

extract We can import all variables into the current scope using a magical feature in Laravel that is often used but is hated by PHPStorm and static analysis tools.

1

2

3

4

5

6

extract(Query::functions());

var_dump($and(

    $query(foo: $eq(5)),

    $query(bar: $eq(10))

));

// INFO: MixedFunctionCall - Cannot call function on mixed

Copy after login

Conclusion

As you can see, function naming in PHP is not that simple when using reserved keywords.

The above is the detailed content of How to overcome PHP's naming limitations to model MongoDB operators. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

The Future of PHP: Adaptations and Innovations The Future of PHP: Adaptations and Innovations Apr 11, 2025 am 12:01 AM

The future of PHP will be achieved by adapting to new technology trends and introducing innovative features: 1) Adapting to cloud computing, containerization and microservice architectures, supporting Docker and Kubernetes; 2) introducing JIT compilers and enumeration types to improve performance and data processing efficiency; 3) Continuously optimize performance and promote best practices.

PHP vs. Python: Understanding the Differences PHP vs. Python: Understanding the Differences Apr 11, 2025 am 12:15 AM

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHP is suitable for web development, with simple syntax and high execution efficiency. 2. Python is suitable for data science and machine learning, with concise syntax and rich libraries.

PHP: Is It Dying or Simply Adapting? PHP: Is It Dying or Simply Adapting? Apr 11, 2025 am 12:13 AM

PHP is not dying, but constantly adapting and evolving. 1) PHP has undergone multiple version iterations since 1994 to adapt to new technology trends. 2) It is currently widely used in e-commerce, content management systems and other fields. 3) PHP8 introduces JIT compiler and other functions to improve performance and modernization. 4) Use OPcache and follow PSR-12 standards to optimize performance and code quality.

Navicat's method to view MongoDB database password Navicat's method to view MongoDB database password Apr 08, 2025 pm 09:39 PM

It is impossible to view MongoDB password directly through Navicat because it is stored as hash values. How to retrieve lost passwords: 1. Reset passwords; 2. Check configuration files (may contain hash values); 3. Check codes (may hardcode passwords).

H5: Tools, Frameworks, and Best Practices H5: Tools, Frameworks, and Best Practices Apr 11, 2025 am 12:11 AM

The tools and frameworks that need to be mastered in H5 development include Vue.js, React and Webpack. 1.Vue.js is suitable for building user interfaces and supports component development. 2.React optimizes page rendering through virtual DOM, suitable for complex applications. 3.Webpack is used for module packaging and optimize resource loading.

PHP's Current Status: A Look at Web Development Trends PHP's Current Status: A Look at Web Development Trends Apr 13, 2025 am 12:20 AM

PHP remains important in modern web development, especially in content management and e-commerce platforms. 1) PHP has a rich ecosystem and strong framework support, such as Laravel and Symfony. 2) Performance optimization can be achieved through OPcache and Nginx. 3) PHP8.0 introduces JIT compiler to improve performance. 4) Cloud-native applications are deployed through Docker and Kubernetes to improve flexibility and scalability.

PHP: A Key Language for Web Development PHP: A Key Language for Web Development Apr 13, 2025 am 12:08 AM

PHP is a scripting language widely used on the server side, especially suitable for web development. 1.PHP can embed HTML, process HTTP requests and responses, and supports a variety of databases. 2.PHP is used to generate dynamic web content, process form data, access databases, etc., with strong community support and open source resources. 3. PHP is an interpreted language, and the execution process includes lexical analysis, grammatical analysis, compilation and execution. 4.PHP can be combined with MySQL for advanced applications such as user registration systems. 5. When debugging PHP, you can use functions such as error_reporting() and var_dump(). 6. Optimize PHP code to use caching mechanisms, optimize database queries and use built-in functions. 7

Composer Expertise: What Makes Someone Skilled Composer Expertise: What Makes Someone Skilled Apr 11, 2025 pm 12:41 PM

To become proficient when using Composer, you need to master the following skills: 1. Proficient in using composer.json and composer.lock files, 2. Understand how Composer works, 3. Master Composer's command line tools, 4. Understand basic and advanced usage, 5. Familiar with common errors and debugging techniques, 6. Optimize usage and follow best practices.

See all articles