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:
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){
// ...
}
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.
When use create
method to a generate a list, you can provide to it a parameters array. The allowed keys are:
uuid
- uuid of listelement-uuid
- uuid for the list elementsheaders
- headers array for the listchunk-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
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');
//..
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'));
// ...
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];
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
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
To delete an element in you list do this:
// ..
$client->getRepository()->deleteElement(
$listUuid,
$elementUuid,
);
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',
]
);
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',
// ..
]
);
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
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
]);
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){
// ...
}
If you have an application which uses Symfony Console, you have some commands avaliable:
iml:cache:flush
to flush the cacheiml:cache:index [<from>] [<to>]
to get full index of items stored in cacheiml: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,
]));
In order to run all the tests, you have two options:
The first way it to install all the drivers on your machine:
- APCU - (install via PECL)
- MEMCACHED - (install via PECL)
- REDIS - (official install guide)
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: ~
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
- 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
If you found an issue or had an idea please refer to this section.
- Mauro Cassani - github
This project is licensed under the MIT License - see the LICENSE.md file for details