fortean/laravel-bitter
| Install | |
|---|---|
composer require fortean/laravel-bitter |
|
| PHP: | >=5.3 |
| License: | MIT |
| Last Updated: | Jun 25, 2014 |
| Links: | GitHub · Packagist |
Laravel 4 Service Provider for Bitter, a PHP port of bitmapist (Python Redis analytics)
laravel-bitter is a Laravel 4 service provider for free-agent/bitter which is a PHP port of the Python bitmapist library. Both libraries use Redis to implement real-time, highly scalable analytics that can answer following questions:
- Has user 123 been online today? This week? This month?
- Has user 123 performed action "X"?
- How many users have been active have this month? This hour?
- How many unique users have performed action "X" this week?
- How many % of users that were active last week are still active?
- How many % of users that were active last month are still active this month?
Using Redis bitmaps you can store events for millions of users in a very little amount of memory (megabytes). You should be careful about using huge ids (e.g. 2^32 or bigger) as this could require larger amounts of memory.
Contents
Installation
Add laravel-bitter to your composer.json file:
"require": {
"laravel-bitter": "dev-master"
}
Use composer to install this package.
$ composer update
Registering the Package
Register the service provider within the providers array found in app/config/app.php:
'providers' => array(
// ...
'Fortean\Bitter\BitterServiceProvider'
)
Add an alias within the aliases array found in app/config/app.php:
'aliases' => array(
// ...
'Bitter' => 'Fortean\Bitter\Facade\Bitter',
)
Basic Usage
One you have registered the Bitter Service Provider and Facade in app/config/app.php, you can create a Bitter instance like so:
$bitter = Bitter::connection();
The Bitter instance returned will use the default Laravel Redis connection. If you want to use the 'foo' Redis connection, make sure the connection is defined in your app/config/database.php file:
'redis' => array(
'cluster' => true,
// ...
'foo' => array(
'host' => '127.0.0.1',
'port' => 6379,
'database' => 2,
),
),
and pass the 'foo' connection name to the connection method:
$bitter = Bitter::connection('foo');
You can also pass a Redis client instance to connection:
$client = Redis::connection('foo');
$bitter = Bitter::connection($client);
Once you have a Bitter instance, you can do the following:
Mark user 123 as active and has played a song:
$bitter
->mark('active', 123)
->mark('song:played', 123);
Note: Please don't use huge ids (e.g. 2^32 or bigger) cause this will require large amounts of memory.
Pass a DateTime (or derviative, e.g. Carbon) as third argument:
$bitter->mark('song:played', 123, new \DateTime('yesterday'));
$bitter->mark('song:played', 123, new \Carbon\Carbon('yesterday'));
To facilitate easier use of the library, I've extended Bitter with a markEvent method that will take either
DateTime objects as above, or a string which will be converted into a Carbon object automatically:
// These calls:
$yesterday = new \Carbon\Carbon('yesterday');
$bitter->markEvent('song:played', 123, $yesterday);
$bitter->markEvent('song:played', 123, new \Carbon\Carbon('yesterday'));
$bitter->markEvent('song:played', 123, 'yesterday');
// Are all equivalent to this:
$bitter->mark('song:played', 123, new \Carbon\Carbon('yesterday'));
To test if user 123 has played a song this week:
$currentWeek = Bitter::weekEvents('song:played');
if ($bitter->in(123, $currentWeek) {
echo 'User with id 123 has played a song this week.';
} else {
echo 'User with id 123 has not played a song this week.';
}
How many users were active yesterday:
$yesterday = new Bitter::dayEvents('active', new \DateTime('yesterday'));
echo $bitter->count($yesterday) . ' users were active yesterday.';
All of the Bitter *Events helpers can take either a DateTime object or a string date descriptor:
// Equivalent calls
$day = Bitter::dayEvents('active', new \DateTime('yesterday'));
$day = Bitter::dayEvents('active', 'yesterday');
Using BitOp
How many users that were active yesterday are also active today:
$today = Bitter::dayEvents('active');
$yesterday = Bitter::dayEvents('active', new \DateTime('yesterday'));
$count = $bitter
->bitOpAnd('bit_op_example', $today, $yesterday)
->count('bit_op_example');
echo $count . ' users were active yesterday and today.';
Note: The bit_op_example key will expire after 60 seconds.
Test if user 123 was active yesterday and is active today:
$today = new Bitter::dayEvents('active');
$yesterday = new Bitter::dayEvents('active', new \DateTime('yesterday'));
$active = $bitter
->bitOpAnd('bit_op_example', $today, $yesterday)
->in(123, 'bit_op_example');
if ($active) {
echo 'User with id 123 was active yesterday and today.';
} else {
echo 'User with id 123 was not active yesterday and today.';
}
Note: Please look at Redis BITOP Command for performance considerations.
Custom date period stats
How many users that were active during a given date period:
$from = new \DateTime('2010-02-14 20:15:30');
$to = new \DateTime('2012-12-21 13:30:45');
$count = $bitter
->bitDateRange('active', 'active_period_example', $from, $to)
->count('active_period_example');
echo $count . ' users were active from "2010-02-14 20:15:30" to "2012-12-21 13:30:45".';
To facilitate easier use of the library, I've extended Bitter with a bitCustomDateRange method that will take either
DateTime objects as above, or a string which will be converted into a Carbon object automatically:
$count = $bitter
->bitCustomDateRange('active', 'active_period_example', '2010-02-14 20:15:30', '2012-12-21 13:30:45')
->count('active_period_example');
echo $count . ' users were active from "2010-02-14 20:15:30" to "2012-12-21 13:30:45".';
Thanks
Thanks to both Amir Salihefendic for the original bitmapist library and Jérémy Romey for his PHP port.
License
This library is licensed under the MIT license.
Related Packages
Use The Redis PHP-Extention In The Laravel Framework With Facde Pattern.