- Manage multiple environment (production/development/test ...)
- Manage dependencies between objects
- Perform a Lazy instantiation
- Perform a Factory pattern
- No external files to configure dependencies
- You can avoid Singleton/Factory pattern from your classes
- PHP5.4+
Create or update your composer.json and run composer update
{
"require": {
"kzykhys/bowl": "1.0"
}
}
$bowl = new \Bowl\Bowl();
$bowl['lang'] = 'en';
$bowl['debug'] = true;
$bowl = new \Bowl\Bowl();
$bowl->share('service_name', function () {
return new stdClass();
});
var_dump($bowl->get('service_name') === $bowl->get('service_name')); // bool(true)
$bowl = new \Bowl\Bowl();
$bowl->factory('service_name', function () {
return new stdClass();
});
var_dump($bowl->get('service_name') === $bowl->get('service_name')); // bool(false)
$bowl = new \Bowl\Bowl();
$bowl->share('driver.mysql', function () {
return new MysqlDriver();
});
$bowl->share('connection', function () {
$c = new Connection();
$c->setDriver($this->get('driver.mysql'));
return $c;
});
$bowl = new \Bowl\Bowl();
$bowl->share('form.type.text', function () {
return new TextType();
}, ['form.type']);
$bowl->share('form.type.email', function () {
return new EmailType();
}, ['form.type']);
$bowl->share('form', function () {
$form = new Form();
foreach ($this->getTaggedServices('form.type') as $service) {
$form->addType($service);
}
return $form;
});
use Bowl\Bowl;
$bowl = new Bowl();
// Common parameters
$bowl['lang'] = 'en';
// Production configuration
$bowl->configure('production', function (Bowl $bowl) {
$bowl['debug'] = false;
$bowl->share('orm.repository', function () {
return new EntityRepository();
});
});
// Development configuration
$bowl->configure('development', function (Bowl $bowl) {
$bowl['debug'] = true;
$bowl->share('orm.repository', function () {
return new MockRepository();
});
});
// Common services
$bowl->share('orm.manager', function () {
return new OrmManager($this->get('orm.repository'));
});
$bowl->share('fixture.loader', function () {
return new Loader($this->get('orm.manager'), $this['debug']);
});
// Set enviroment manually
$bowl->env('production');
// Or using system's environment variable
$bowl->env(getenv('APP_ENV') ? getenv('APP_ENV') : 'production');
<?php
require __DIR__ . '/../vendor/autoload.php';
$bowl = new \Bowl\Bowl();
// Set a parameter
$bowl['debug'] = false;
// Shared service
$bowl->share('ciconia.renderer', function () {
return new \Ciconia\Renderer\HtmlRenderer();
});
// Tagged service
$bowl->share('ciconia.extension.table', function () {
return new \Ciconia\Extension\Gfm\TableExtension();
}, ['ciconia.extension']);
// This example shows how to manage services using tags
$bowl->share('ciconia', function () {
$ciconia = new \Ciconia\Ciconia();
// $bowl is bind to this closure, so you can access $this as Bowl.
if ($this['debug']) {
$ciconia = new \Ciconia\Diagnose\Ciconia();
}
// Resolve dependencies
$ciconia->setRenderer($this->get('ciconia.renderer'));
// All services tagged as "ciconia.extension"
foreach ($this->getTaggedServices('ciconia.extension') as $extension) {
$ciconia->addExtension($extension);
}
return $ciconia;
});
// Get the object
$ciconia = $bowl->get('ciconia');
echo $ciconia->render('Markdown is *awesome*');
// Create a new instance even if this is a shared object
$ciconia = $bowl->reset('ciconia')->get('ciconia');
echo $ciconia->render('Markdown is *awesome*');
You can configure Bowl based on environment flags such as production and development.
$bowl = new \Bowl\Bowl();
$bowl->configure('prod', function (\Bowl\Bowl $bowl) {
$bowl['debug'] = false;
});
You have to call env()
to apply one of environments.
$bowl = new \Bowl\Bowl();
$bowl->configure('prod', function (\Bowl\Bowl $bowl) {
$bowl['debug'] = false;
});
$bowl->env('prod');
Register a shared service
$bowl = new \Bowl\Bowl();
$bowl->share('logger', function () {
return new Logger();
});
$bowl->get('logger')->log($message);
Register a factory service
$bowl = new \Bowl\Bowl();
$bowl->share('date.now', function () {
return new \DateTime('now');
});
$bowl->get('date.now')->format('r');
Extend a service definition
$bowl = new \Bowl\Bowl();
$bowl->share('logger', function () {
return new Logger();
});
$bowl->extend('logger', function (LoggerInterface $logger) {
$logger->setPath(__DIR__.'/../app/logs');
return $logger;
});
$bowl->get('logger')->log($message);
Get an object
$bowl = new \Bowl\Bowl();
$bowl['debug'] = true;
$bowl->factory('filesystem', function () {
return new Filesystem();
});
$bowl->share('logger', function () {
if ($this['debug']) {
return new ConsoleLogger();
} else {
return new FilesystemLogger($this->get('filesystem'));
}
});
$logger = $bowl->get('logger');
Get services having a tag
$bowl = new \Bowl\Bowl();
$bowl->share('transport.smtp', function () {
return new SmtpTransport();
}, ['email.transport']);
$bowl->share('transport.sendmail', function () {
return new SendmailTransport();
}, ['email.transport']);
$bowl->share('mailer', function () {
$mailer = new Mailer();
foreach ($this->getTaggedServices('email.transport') as $service) {
$mailer->addTransport($service);
}
return $mailer;
});
$bowl->get('mailer')->send($mimeMessage);
Re-instantiate the object, even if the service is shared object.
This is unsafe operation
$bowl = new \Bowl\Bowl();
$bowl->share('registry', function () {
return new Registry();
});
try {
$bowl->get('registry')->getManager()->flush();
} catch (\Exception $e) {
$bowl->reset('registry');
}
Feel free to fork and send a pull request.
The MIT License
Kazuyuki Hayashi (@kzykhys)