2010-01-04 14:26:20 +00:00
< ? php
2010-08-20 22:09:55 +01:00
namespace Symfony\Component\DependencyInjection ;
2010-01-04 14:26:20 +00:00
2010-08-20 22:09:55 +01:00
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface ;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag ;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag ;
2010-06-27 17:28:29 +01:00
2010-01-04 14:26:20 +00:00
/*
2010-04-07 01:51:29 +01:00
* This file is part of the Symfony framework .
2010-01-04 14:26:20 +00:00
*
* ( c ) Fabien Potencier < fabien . potencier @ symfony - project . com >
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE .
*/
/**
* Container is a dependency injection container .
*
2010-06-27 17:28:29 +01:00
* It gives access to object instances ( services ) .
2010-01-04 14:26:20 +00:00
*
* Services and parameters are simple key / pair stores .
*
2011-01-03 08:07:06 +00:00
* Parameter and service keys are case insensitive .
2010-01-04 14:26:20 +00:00
*
* A service id can contain lowercased letters , digits , underscores , and dots .
* Underscores are used to separate words , and dots to group services
* under namespaces :
*
* < ul >
* < li > request </ li >
* < li > mysql_session_storage </ li >
* < li > symfony . mysql_session_storage </ li >
* </ ul >
*
* A service can also be defined by creating a method named
* getXXXService (), where XXX is the camelized version of the id :
*
* < ul >
* < li > request -> getRequestService () </ li >
* < li > mysql_session_storage -> getMysqlSessionStorageService () </ li >
* < li > symfony . mysql_session_storage -> getSymfony_MysqlSessionStorageService () </ li >
* </ ul >
*
* The container can have three possible behaviors when a service does not exist :
*
* * EXCEPTION_ON_INVALID_REFERENCE : Throws an exception ( the default )
* * NULL_ON_INVALID_REFERENCE : Returns null
* * IGNORE_ON_INVALID_REFERENCE : Ignores the wrapping command asking for the reference
* ( for instance , ignore a setter if the service does not exist )
*
2010-10-17 12:45:15 +01:00
* @ author Fabien Potencier < fabien . potencier @ symfony - project . com >
2010-01-04 14:26:20 +00:00
*/
2010-11-15 09:05:16 +00:00
class Container implements ContainerInterface
2010-01-04 14:26:20 +00:00
{
2010-06-27 17:28:29 +01:00
protected $parameterBag ;
protected $services ;
2010-05-06 12:25:53 +01:00
/**
* Constructor .
*
2010-07-27 14:33:28 +01:00
* @ param ParameterBagInterface $parameterBag A ParameterBagInterface instance
2010-05-06 12:25:53 +01:00
*/
2010-06-27 17:28:29 +01:00
public function __construct ( ParameterBagInterface $parameterBag = null )
2010-01-04 14:26:20 +00:00
{
2010-06-27 17:28:29 +01:00
$this -> parameterBag = null === $parameterBag ? new ParameterBag () : $parameterBag ;
$this -> services = array ();
$this -> set ( 'service_container' , $this );
2010-01-04 14:26:20 +00:00
}
2010-05-06 12:25:53 +01:00
/**
2010-07-16 08:15:22 +01:00
* Freezes the container .
*
* This method does two things :
*
* * Parameter values are resolved ;
2011-01-14 17:43:51 +00:00
* * The parameter bag is frozen .
2010-05-06 12:25:53 +01:00
*/
2010-06-27 17:28:29 +01:00
public function freeze ()
2010-05-06 12:25:53 +01:00
{
2010-07-16 08:15:22 +01:00
$this -> parameterBag -> resolve ();
2010-06-27 17:28:29 +01:00
$this -> parameterBag = new FrozenParameterBag ( $this -> parameterBag -> all ());
2010-05-06 12:25:53 +01:00
}
/**
2010-06-27 17:28:29 +01:00
* Returns true if the container parameter bag are frozen .
2010-05-06 12:25:53 +01:00
*
2010-06-27 17:28:29 +01:00
* @ return Boolean true if the container parameter bag are frozen , false otherwise
2010-05-06 12:25:53 +01:00
*/
2010-06-27 17:28:29 +01:00
public function isFrozen ()
2010-05-06 12:25:53 +01:00
{
2010-06-27 17:28:29 +01:00
return $this -> parameterBag instanceof FrozenParameterBag ;
2010-05-06 12:25:53 +01:00
}
/**
2010-06-27 17:28:29 +01:00
* Gets the service container parameter bag .
2010-05-06 12:25:53 +01:00
*
2010-07-27 14:33:28 +01:00
* @ return ParameterBagInterface A ParameterBagInterface instance
2010-05-06 12:25:53 +01:00
*/
2010-06-27 17:28:29 +01:00
public function getParameterBag ()
2010-05-06 12:25:53 +01:00
{
2010-06-27 17:28:29 +01:00
return $this -> parameterBag ;
2010-05-06 12:25:53 +01:00
}
/**
2010-06-27 17:28:29 +01:00
* Gets a parameter .
2010-05-06 12:25:53 +01:00
*
2010-06-27 17:28:29 +01:00
* @ param string $name The parameter name
2010-05-06 12:25:53 +01:00
*
* @ return mixed The parameter value
*
* @ throws \InvalidArgumentException if the parameter is not defined
*/
public function getParameter ( $name )
{
2010-06-27 17:28:29 +01:00
return $this -> parameterBag -> get ( $name );
2010-05-06 12:25:53 +01:00
}
2010-08-25 23:30:10 +01:00
/**
* Checks if a parameter exists .
*
* @ param string $name The parameter name
*
2010-10-16 11:32:57 +01:00
* @ return boolean The presence of parameter in container
2010-08-25 23:30:10 +01:00
*/
public function hasParameter ( $name )
{
return $this -> parameterBag -> has ( $name );
}
2010-05-06 12:25:53 +01:00
/**
2010-06-27 17:28:29 +01:00
* Sets a parameter .
2010-05-06 12:25:53 +01:00
*
* @ param string $name The parameter name
* @ param mixed $parameters The parameter value
*/
public function setParameter ( $name , $value )
{
2010-06-27 17:28:29 +01:00
$this -> parameterBag -> set ( $name , $value );
2010-05-06 12:25:53 +01:00
}
/**
* Sets a service .
*
* @ param string $id The service identifier
* @ param object $service The service instance
*/
2010-06-27 17:28:29 +01:00
public function set ( $id , $service )
2010-01-04 14:26:20 +00:00
{
2011-01-03 08:07:06 +00:00
$this -> services [ strtolower ( $id )] = $service ;
2010-01-04 14:26:20 +00:00
}
2010-05-06 12:25:53 +01:00
/**
* Returns true if the given service is defined .
*
* @ param string $id The service identifier
*
* @ return Boolean true if the service is defined , false otherwise
*/
2010-06-27 17:28:29 +01:00
public function has ( $id )
2010-01-19 12:29:28 +00:00
{
2011-01-03 08:07:06 +00:00
$id = strtolower ( $id );
2010-05-06 12:25:53 +01:00
return isset ( $this -> services [ $id ]) || method_exists ( $this , 'get' . strtr ( $id , array ( '_' => '' , '.' => '_' )) . 'Service' );
2010-01-19 12:29:28 +00:00
}
2010-05-06 12:25:53 +01:00
/**
* Gets a service .
*
2010-06-27 17:28:29 +01:00
* If a service is both defined through a set () method and
2010-05-06 12:25:53 +01:00
* with a set * Service () method , the former has always precedence .
*
* @ param string $id The service identifier
* @ param int $invalidBehavior The behavior when the service does not exist
*
* @ return object The associated service
*
* @ throws \InvalidArgumentException if the service is not defined
*
* @ see Reference
*/
2010-06-27 17:28:29 +01:00
public function get ( $id , $invalidBehavior = self :: EXCEPTION_ON_INVALID_REFERENCE )
2010-01-04 14:26:20 +00:00
{
2011-01-06 13:18:28 +00:00
static $loading = array ();
2011-01-03 08:07:06 +00:00
$id = strtolower ( $id );
2010-05-06 12:25:53 +01:00
2010-05-07 15:09:11 +01:00
if ( isset ( $this -> services [ $id ])) {
2010-05-06 12:25:53 +01:00
return $this -> services [ $id ];
}
2011-01-06 13:18:28 +00:00
if ( isset ( $loading [ $id ])) {
throw new \LogicException ( sprintf ( 'Circular reference detected for service "%s" (services currently loading: %s).' , $id , implode ( ', ' , array_keys ( $loading ))));
}
2010-06-27 17:28:29 +01:00
if ( method_exists ( $this , $method = 'get' . strtr ( $id , array ( '_' => '' , '.' => '_' )) . 'Service' )) {
2011-01-06 13:18:28 +00:00
$loading [ $id ] = true ;
$service = $this -> $method ();
unset ( $loading [ $id ]);
return $service ;
2010-05-06 12:25:53 +01:00
}
2010-05-07 15:09:11 +01:00
if ( self :: EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior ) {
2010-05-06 12:25:53 +01:00
throw new \InvalidArgumentException ( sprintf ( 'The service "%s" does not exist.' , $id ));
}
2010-01-04 14:26:20 +00:00
}
2010-05-06 12:25:53 +01:00
/**
* Gets all service ids .
*
* @ return array An array of all defined service ids
*/
public function getServiceIds ()
2010-01-04 14:26:20 +00:00
{
2010-05-06 12:25:53 +01:00
$ids = array ();
$r = new \ReflectionClass ( $this );
2010-05-07 15:09:11 +01:00
foreach ( $r -> getMethods () as $method ) {
2010-05-08 14:32:30 +01:00
if ( preg_match ( '/^get(.+)Service$/' , $name = $method -> getName (), $match )) {
2010-05-06 12:25:53 +01:00
$ids [] = self :: underscore ( $match [ 1 ]);
}
}
return array_merge ( $ids , array_keys ( $this -> services ));
2010-01-04 14:26:20 +00:00
}
2010-05-06 12:25:53 +01:00
static public function camelize ( $id )
{
2010-10-20 19:33:59 +01:00
return preg_replace ( array ( '/(?:^|_)+(.)/e' , '/\.(.)/e' ), array ( " strtoupper(' \\ 1') " , " '_'.strtoupper(' \\ 1') " ), $id );
2010-05-06 12:25:53 +01:00
}
static public function underscore ( $id )
{
return strtolower ( preg_replace ( array ( '/([A-Z]+)([A-Z][a-z])/' , '/([a-z\d])([A-Z])/' ), array ( '\\1_\\2' , '\\1_\\2' ), strtr ( $id , '_' , '.' )));
}
2010-01-04 14:26:20 +00:00
}