In-memory List is a PHP library that allows you to create and store in memory your lists, and then quickly retrieve and perform queries on it.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
app
bin
config
examples
install
src
tests
.dockerignore
.gitignore
.php_cs
.travis.yml
Dockerfile
LICENSE.md
README.md
composer.json
composer.lock
contributors.md
docker-compose.yml
phpunit.xml.dist

README.md

In-memory List

Scrutinizer Code Quality SensioLabsInsight Build Status Codacy Badge license Packagist

In-memory List easily allows you to create and save your lists in memory.

If you are looking for a caching system for your lists this library is suitable for you.

Grab your lists from your API, your database or whatever you want and store them in memory: then, you can quickly retrieve your lists from cache, sorting and performing queries on them.

This package uses:

Basic Usage

To create and store in memory you list do the following:

use InMemoryList\Application\Client;

$array = [
    ...
]

$client = new Client();
$collection = $client->create($array);

foreach ($collection as $element){
    // ...
}

Drivers

Avaliable drivers:

  • apcu
  • memcached
  • pdo
  • redis (default driver)
use InMemoryList\Application\Client;

// Apcu, no configuration is needed
$client = new Client('apcu');
// ..
use InMemoryList\Application\Client;

// Memcached, you can pass one or more servers
$memcached_parameters = [
    [
        'host' => 'localhost',
        'port' => 11211
    ],
    [
        'host' => 'localhost',
        'port' => 11222
    ],
    // etc..
];

$client = new Client('memcached', $memcached_parameters);
// ..
use InMemoryList\Application\Client;

// Pdo
$pdo_parameters = [
    'driver' => 'mysql',
    'host' => '127.0.0.1',
    'username' => 'root',
    'password' => '',
    'database' => 'in-memory-list'
    'port' => '3306'
];

$client = new Client('pdo', $pdo_parameters);
// ..
use InMemoryList\Application\Client;

// you have to use arrays
// you can't use URI string like 'tcp://10.0.0.1:6379'
// please refer to PRedis library documentation
$redis_parameters = [
    'scheme' => 'tcp',
    'host' => '127.0.0.1',
    'port' => 6379,
    'options' => [
        'profile' => '3.0',
    ],
];

$client = new Client('redis', $redis_parameters);
// ..

Refer to official page for more details on PRedis connection.

Parameters

When use create method to a generate a list, you can provide to it a parameters array. The allowed keys are:

  • uuid - uuid of list
  • element-uuid - uuid for the list elements
  • headers - headers array for the list
  • chunk-size - the chunks size in which the array will be splitted (integer) **
  • ttl - time to live of the list (in seconds) **

** = NOT AVALIABLE WITH PDO DRIVER

uuid

You can assign an uuid to your list (instead, a uuid will be generated):

use InMemoryList\Application\Client;

$array = [
    ...
]

$client = new Client();
$client->create($array, [
    'uuid' => 'simple-array'
]);

// And now you can retrive the list:
$simpleArray = $client->getRepository()->findListByUuid('simple-array');

//..

headers

You can set a headers array to your list:

use InMemoryList\Application\Client;

$array = [
    ...
]

$headers = [
    'expires' => 'Sat, 26 Jul 1997 05:00:00 GMT',
    'hash' => 'ec457d0a974c48d5685a7efa03d137dc8bbde7e3'
];

$client = new Client();
$collection = $client->create($array, [
    'uuid' => 'simple-array',
    'headers' => $headers
]);

// get headers
var_dump($client->getRepository()->getHeaders('simple-array'));

// ...

element-uuid

You can assign an uuid to list elemens (instead, a uuid will be generated). Consider this array:

$simpleArray = [
    [
        "userId" => 1,
        "id" => 1,
        "title" => "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
        "body" =>  "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
    ],
    ...
]

Maybe you would use id key as uuid in your list:

use InMemoryList\Application\Client;

$client = new Client();
$collection = $client->create($simpleArray, [
    'uuid' => 'simple-array',
    'element-uuid' => 'id'
]);

// now to retrieve a single element, you can simply do:
$itemWithId1 = $collection[1];

chunk-size

You can specify the number of elements of each chunk in which the original array will be splitted. The default value is 1000.

use InMemoryList\Application\Client;

$client = new Client();
$collection = $client->create($array, [
    'uuid' => 'simple-array',
    'element-uuid' => 'id',
    'chunk-size' => 1500
]);

// ..

PLEASE NOTE THAT chunk-size IS NOT AVALIABLE WITH PDO DRIVER

ttl

You can specify a ttl (in seconds) for your lists:

use InMemoryList\Application\Client;

$client = new Client();
$collection = $client->create($array, [
    'uuid' => 'simple-array',
    'element-uuid' => 'id',
    'ttl' => 3600
]);

// ..

PLEASE NOTE THAT ttl IS NOT AVALIABLE WITH PDO DRIVER

Delete an element

To delete an element in you list do this:

// ..
$client->getRepository()->deleteElement(
    $listUuid, 
    $elementUuid,
);

Push an element

To push an element in you list, use pushElement function. You must provide the list uuid, the element uuid and element data (data must be consistent - see Validation). Look at this example:

// ..
$client->pushElement(
    'fake-list-uuid',
    5001,
    [
        'id' => 5001,
        'name' => 'Name 5001',
        'email' => 'Email 5001',
    ]
);

Update an element

To update an element in you list, use updateElement function. You must provide the list uuid, the element uuid and element data (data must be consistent - see Validation). Look at this example:

// ..
$client->getRepository()->updateElement(
    'list-to-update', 
    4325, 
    [
        'id' => 4325,
        'title' => 'New Title',
        // ..
    ]
);

Ttl

You can update ttl of a persisted list with updateTtl method, and retrive the ttl with getTtl function:

// ...
$client->getRepository()->updateTtl(
    'your-list-uuid',
    3600 // ttl in seconds
);

// get Ttl of the list
$client->getRepository()->getTtl('your-list-uuid'); // 3600

PLEASE NOTE THAT ttl IS NOT AVALIABLE WITH PDO DRIVER

Validation (Data consistency)

Please note that your data must be consistent:

// simple string list
$stringArray = [
    'Lorem Ipsum',
    'Ipse Dixit',
    'Dolor facium',
];

$collection = $client->create($stringArray, [
    'uuid' => 'string-array',
    'ttl' => 3600
]);

// array list, you must provide elements with consistent structure
$listArray[] = [
    'id' => 1,
    'title' => 'Lorem Ipsum',
];
$listArray[] = [
    'id' => 2,
    'title' => 'Ipse Dixit',
];
$listArray[] = [
    'id' => 3,
    'title' => 'Dolor facium',
];

$collection = $client->create($listArray, [
    'uuid' => 'simple-array',
    'element-uuid' => 'id',
    'ttl' => 3600
]);

// entity list, the objects must have the same properties 
$entityArray[] = new User(1, 'Mauro');
$entityArray[] = new User(2, 'Cristina');
$entityArray[] = new User(3, 'Lilli');

$collection = $client->create($entityArray, [
    'uuid' => 'entity-array',
    'element-uuid' => 'id',
    'ttl' => 3600
]);

Instead, a ListElementNotConsistentException will be thrown. Example:


// ListElementNotConsistentException will be thrown
$listArray[] = [
    'id' => 1,
    'title' => 'Lorem Ipsum',
];
$listArray[] = [
    'id' => 2,
    'non-consistent-key' => 'Ipse Dixit',
];
$listArray[] = [
    'id' => 3,
    'title' => 'Dolor facium',
];

$collection = $client->create($listArray, [
    'uuid' => 'simple-array',
    'element-uuid' => 'id',
    'ttl' => 3600
]);

Sorting and Quering

You can perform queries on your list. This library uses Array Query, please refer to it for the official documentation.

use ArrayQuery\QueryBuilder;

// ..

$list = $client->getRepository()->findListByUuid('simple-array');

$qb = QueryBuilder::create($list);
$qb
    ->addCriterion('id', '3', '>')
    ->sortedBy('id', 'DESC');
  
// get results    
foreach ($qb->getResults() as $element){
    // ...
}

Commands

If you have an application which uses Symfony Console, you have some commands avaliable:

  • iml:cache:flush to flush the cache
  • iml:cache:index [<from>] [<to>] to get full index of items stored in cache
  • iml:cache:schema:create Create database schema (only for PDO driver)
  • iml:cache:schema:destroy Destroys database schema (only for PDO driver)
  • iml:cache:statistics to get cache statistics

You can register the commands in your app, consider this example:

#!/usr/bin/env php

<?php
// Example of a Silex Application 'bin/console' file
// we use \Knp\Provider\ConsoleServiceProvider as ConsoleServiceProvider, use what you want

set_time_limit(0);

require __DIR__.'/../vendor/autoload.php';

$app = new Silex\Application();
$app->register(new \Knp\Provider\ConsoleServiceProvider(), array(
    'console.name'              => '...',
    'console.version'           => '...',
    'console.project_directory' => __DIR__.'/..'
));

$console = $app['console'];

// add commands here
...
$console->add(new \InMemoryList\Command\CreateSchemaCommand(...));
$console->add(new \InMemoryList\Command\DestroySchemaCommand(...));
$console->add(new \InMemoryList\Command\FlushCommand(...));
$console->add(new \InMemoryList\Command\IndexCommand(...));
$console->add(new \InMemoryList\Command\StatisticsCommand(...));
$console->run();

You have to provide to commands your driver and connection parameters array. Example:

$console->add(new \InMemoryList\Command\FlushCommand('redis', [
    'host' => '127.0.0.1',
    'port' => 6379,
]));

Testing

In order to run all the tests, you have two options:

1. Install all the drivers on your machine

The first way it to install all the drivers on your machine:

Once installed all the drivers, create a file called config/parameters.yml and paste in the content of config/parameters.dist.yml. Finally, change your configuration if needed:

redis_parameters:
  scheme: 'tcp'
  host: '127.0.0.1'
  port: '6379'
  options:
    profile: '3.2'

memcached_parameters:
  host: 'localhost'
  port: '11211'

pdo_parameters:
  driver: 'mysql'
  host: '127.0.0.1'
  username: 'root'
  password: ~
  database: 'in-memory-list'
  port: '3306'
  options: ~  

2. Run the project with Docker

You can run the project with Docker.

STEP1: Make the build

docker-compose build

STEP2: Raise the app

docker-compose up -d

STEP3: Enter in the docker container

docker exec -it inmemorylist_app_1 bash

STEP4: Create the schema and run the tests in the container

php bin/console iml:cache:schema:create

vendor/bin/phpunit

Built With

  • PRedis - Flexible and feature-complete Redis client for PHP and HHVM
  • ramsey/uuid - A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).
  • Symfony Console - Symfony Console Component

Support

If you found an issue or had an idea please refer to this section.

Authors

License

This project is licensed under the MIT License - see the LICENSE.md file for details