Provides an object-oriented API to query in-memory collections in a SQL-style.

Overview

POQ - PHP Object Query

Minimum PHP Version CI Latest Unstable Version License

Install

composer require alexandre-daubois/poq 1.0.0-beta2

That's it, ready to go! ๐ŸŽ‰

Usage

Here is the set of data we're going to use in the follow examples:

$cities = [
    new City('Lyon', [
        new Person([
            new Child('Hubert', age: 30),
            new Child('Aleksandr', age: 18),
            new Child('Alexandre', age: 26),
            new Child('Alex', age: 25),
        ], height: 181),
        new Person([
            new Child('Fabien', age: 23),
            new Child('Nicolas', age: 8),
        ], height: 176),
        new Person([
            new Child('Alexis', age: 33),
            new Child('Pierre', age: 5),
        ], height: 185)
    ], minimalAge: 21),
    new City('Paris', [
        new Person([
            new Child('Will', age: 33),
            new Child('Alix', age: 32),
            new Child('Alan', age: 45),
        ], height: 185)
    ], minimalAge: 45)
];

The ObjectQuery object

The ObjectQuery object allows you to easily fetch deep information in your collections with ease. Just like Doctrine's QueryBuilder, plenty of utils methods are present for easy manipulation.

Moreover, you're able to create your query step-by-step and conditionally if needed. To create a simple query, all you need to do is call ObjectQuery's from factory, and pass your collection as its source:

use ObjectQuery\ObjectQuery;

$query = ObjectQuery::from($this->cities, 'city');

From here, you're able to manipulate your collections and fetch data. First, let's see how to filter your collections. Note that the city argument is optional and defines an alias for the current collection. By default, the alias is _. Each alias must be unique in the query, meaning it is mandatory you pass an alias if you are dealing with deep collections. Defining an alias allows you to reference to the object later in the query. See the selectMany operation explanation for more details.

Modifiers (filtering, ordering, limiting, etc.)

Modifiers allow to filter results, order them, limit them and so on.

๐Ÿ”€ Modifiers can be given to the query in any order, as they are only applied when an operation is called.

Where

Usage

where, which takes a callback as an argument. This callback must return a boolean value.

use ObjectQuery\ObjectQuery;

$query = (ObjectQuery::from($this->cities, 'city'))
    ->where(
        function(City $city) {
            return \str_contains($city->name, 'Lyon') || \in_array($city->name, ['Paris', 'Rouen']);
        }
    );

Order by

orderBy, which will order the collection. If the collection only contains scalar values, then you only have to pass an order. If your collection contains objects, you have to pass the order as well as the field to order on. Available orders are: QueryOrder::Ascending, QueryOrder::Descending, QueryOrder::None and QueryOrder::Shuffle.

use ObjectQuery\ObjectQuery;
use ObjectQuery\ObjectQueryOrder;

$query = (ObjectQuery::from($this->cities))
    ->orderBy(ObjectQueryOrder::Ascending, 'name');

Offset

offset modifier changes the position of the first element that will be retrieved from the collection. This is particularly useful when doing pagination, in conjunction with the limit modifier. The offset must be a positive integer, or null to remove any offset.

use ObjectQuery\ObjectQuery;

$query = ObjectQuery::from($this->cities);

// Skip the 2 first cities of the collection and fetch the rest
$query->offset(2)
    ->select();

// Unset any offset, no data will be skipped
$query->offset(null)
    ->select();

Limit

The limit modifier limit the number of results that will be used by different operations, such as select. The limit must be a positive integer, or null to remove any limit.

use ObjectQuery\ObjectQuery;

$query = ObjectQuery::from($this->cities);

// Only the first 2 results will be fetched by the `select` operation
$query->limit(2)
    ->select();

// Unset any limitation, all matching results will be used in the `select` operations
$query->limit(null)
    ->select();

Operations

Operations allow you to fetch filtered data in a certain format. Here is a list of the available operations and how to use them.

Select

This is the most basic operation. It returns filtered data of the query. It is possible to pass the exact field we want to retrieve, as well as multiple fields. If no argument is passed to select, it will retrieve the whole object. You must not pass any argument when dealing with scalar collections.

use ObjectQuery\ObjectQuery;

$query = ObjectQuery::from($this->cities);

// Retrieve the whole object
$query->select();

// Retrieve one field
$query->select('name');

// Retrieve multiple fields
$query->select(['name', 'minimalAge']);

Select One

When querying a collection, and we know in advance that only one result is going to match, this could be redundant to use select and retrieve result array's first element everytime. selectOne is designed exactly for this case. The behavior of this operation is the following:

  • If a single result is found, it will be returned directly without enclosing it in an array of 1 element.
  • If no result is found, the selectOne operation returns null.
  • If more than on result is found, then a NonUniqueResultException is thrown.
use ObjectQuery\Exception\NonUniqueResultException;

$query = (ObjectQuery::from($this->cities, 'city'))
    ->where(fn($city) => $city->name === 'Lyon');

try {
    $city = $query->selectOne(); // $city is an instance of City

    // You can also query a precise field
    $cityName = $query->selectOne('name'); // $cityName is a string
} catch (NonUniqueResultException) {
    // ...
}

Select Many

This operation allows you to go deeper in a collection. Let's say your collection contains many objects with collections inside them, this is what you're going to use to fetch and filter collections.

Note that we defined an alias for city, which allows to reference the parent city in the last where call.

use ObjectQuery\ObjectQuery;
use ObjectQuery\ObjectQueryContextEnvironment;

$query = (ObjectQuery::from($this->cities, 'city'))
    ->where(fn($city) => \in_array($city->name, ['Paris', 'Rouen']))
    ->selectMany('persons', 'person')
        ->where(fn($person) => $person->height >= 180)
        ->selectMany('children', 'child')
            ->where(fn($child, ObjectQueryContextEnvironment $context) => \str_starts_with($child->name, 'Al') && $child->age >= $context->get('city')->minimalAge);

Like from, selectMany also takes an alias as an argument. This way, you will be able to reference ancestors in your where calls, as shown in the above example.

Count

This operation returns the size of the current filtered collection:

$query = ObjectQuery::from($this->cities);

$query->count();

Concat

This operation will concatenate the collection with a given separator. If you're dealing with a scalar collection, there is no mandatory argument. If dealing with collections of objects, the field argument must be passed.

$query = ObjectQuery::from($this->cities);

$query->concat(', ', 'name');

Each

This operation allows you to pass a callback, which will be applied to each element of the filtered collection. You can see this as a foreach.

$query = ObjectQuery::from($this->cities);

// Append an exclamation point to every city name
$query->each(fn($element) => $element->name.' !');

Min and Max

These operations will return the maximum and the minimum of the collection. You can use this on scalar collections. Internally, these operations use min() and max() functions of the Standard PHP Library, so the same rules apply.

use ObjectQuery\ObjectQuery;

$query = (ObjectQuery::from($this->cities))
        ->selectMany('persons', 'person')
            ->selectMany('children', 'child');

$query->min('age'); // 5
$query->max('age'); // 45
$query->min('name'); // "Alan"
$query->max('name'); // "Will"

Sum

sum returns the sum of a collection. If the collection contains objects, a field must be provided in order to calculate the sum of it. This only works with collections of numerics, and an exception is thrown if any item of the collection returns false to the \is_numeric() function.

use ObjectQuery\ObjectQuery;

$query = (ObjectQuery::from($this->cities))
        ->selectMany('persons', 'person')
            ->selectMany('children', 'child');

$query->sum('age');

Average

average returns the average of a collection. If the collection contains objects, a field must be provided in order to calculate the average of it. This only works with collections of numerics, and an exception is thrown if any item of the collection returns false to the \is_numeric() function.

use ObjectQuery\ObjectQuery;

$query = (ObjectQuery::from($this->cities))
        ->selectMany('persons', 'person')
            ->selectMany('children', 'child');

$query->average('age');
You might also like...
Strings Package provide a fluent, object-oriented interface for working with multibyte string

Strings Package provide a fluent, object-oriented interface for working with multibyte string, allowing you to chain multiple string operations together using a more readable syntax compared to traditional PHP strings functions.

An object oriented wrapper around PHP's built-in server.
An object oriented wrapper around PHP's built-in server.

Statix Server Requirements PHP 8 minumum Installation composer require statix/server Basic Usage To get started, ensure the vendor autoload script is

PHP Unoconv - An Object Oriented library which allow easy to use file conversion with Unoconv.

An Object Oriented library which allow easy to use file conversion with Unoconv. Install The recommended way to install PHP-Unoconv is thr

The XP Framework is an all-purpose, object oriented PHP framework.

XP Framework Core This is the XP Framework's development checkout. Installation If you just want to use the XP Framework, grab a release using compose

Your alter ego object. Takes the best of object and array worlds.

Supporting Opensource formapro\values is an MIT-licensed open source project with its ongoing development made possible entirely by the support of com

A Phalcon paginator adapter for Phalcon Collections

Phalcon Collection Paginator A Phalcon paginator adapter for Phalcon Collections Why create this? Being familiar with the various Pagination data adap

This Repo is a storage of Postman collections for Magento

Magento Postman repository This Repository is a storage of Postman collections for Magento. If you have what to share, you are welcome to contribute a

Get the system resources in PHP, as memory, number of CPU'S, Temperature of CPU or GPU, Operating System, Hard Disk usage, .... Works in Windows & Linux

system-resources. A class to get the hardware resources We can get CPU load, CPU/GPU temperature, free/used memory & Hard disk. Written in PHP It is a

Releases(1.0.0-beta2)
Owner
Alexandre Daubois
Symfony Developper at @sensiolabs
Alexandre Daubois
laminas-memory manages data in an environment with limited memory

Memory objects (memory containers) are generated by the memory manager, and transparently swapped/loaded when required.

Laminas Project 5 Jul 26, 2022
zend-memory manages data in an environment with limited memory

Memory objects (memory containers) are generated by the memory manager, and transparently swapped/loaded when required.

Zend Framework 16 Aug 29, 2020
YCOM Impersonate. Login as selected YCOM user ๐Ÿง™โ€โ™‚๏ธin frontend.

YCOM Impersonate Login as selected YCOM user in frontend. Features: Backend users with admin rights or YCOM[] rights, can be automatically logged in v

Friends Of REDAXO 17 Sep 12, 2022
Object-Oriented API for PHP streams

Streamer Streamer is an Object-Oriented API for PHP streams. Why should I use Streams? A stream is a flow of bytes from one container to the other. Yo

Francois Zaninotto 270 Dec 21, 2022
A simple Object Oriented wrapper for Linear API, written with PHP.

PHP Linear API A simple Object Oriented wrapper for Linear API, written with PHP. NOTE You should take a look Linear GraphQL API Schema for all nodes

Mustafa Kรœร‡รœK 6 Sep 2, 2022
QuidPHP/Main is a PHP library that provides a set of base objects and collections that can be extended to build something more specific.

QuidPHP/Main is a PHP library that provides a set of base objects and collections that can be extended to build something more specific. It is part of the QuidPHP package and can also be used standalone.

QuidPHP 4 Jul 2, 2022
An article about alternative solution for convert object into a JSON Object for your api.

Do we really need a serializer for our JSON API? The last years I did build a lot of JSON APIs but personally was never happy about the magic of using

Alexander Schranz 1 Feb 1, 2022
MOP is a php query handling and manipulation library providing easy and reliable way to manipulate query and get result in a fastest way

Mysql Optimizer mysql optimizer also known as MOP is a php query handling and manipulation library providing easy and reliable way to manipulate query

null 2 Nov 20, 2021
the examples of head first object oriented analysis & design - in PHP

Head First object oriented analysis & design in (PHP) after cloning the repository, you have to install the project's dependancies by running the foll

Muhammed ElFeqy 3 Oct 16, 2021
PHP FFmpeg - An Object Oriented library to convert video/audio files with FFmpeg / AVConv

PHP FFmpeg An Object Oriented library to convert video/audio files with FFmpeg / AVConv. Check another amazing repo: PHP FFMpeg extras, you will find

Alchemy 10 Dec 31, 2022