ObjectFactory
Construct objects from configuration instructions
Loading...
Searching...
No Matches
Wikimedia\ObjectFactory\ObjectFactory Class Reference

Construct objects based on a specification array. More...

+ Collaboration diagram for Wikimedia\ObjectFactory\ObjectFactory:

Public Member Functions

 __construct (ContainerInterface $serviceContainer)
 
 createObject ( $spec, array $options=[])
 Instantiate an object based on a specification array.
 

Static Public Member Functions

static getObjectFromSpec ( $spec, array $options=[])
 Instantiate an object based on a specification array.
 

Static Protected Member Functions

static validateSpec ( $spec, array $options)
 Convert a string or callable to a spec array.
 
static expandClosures (array $list)
 Iterate a list and call any closures it contains.
 

Protected Attributes

ContainerInterface $serviceContainer
 

Detailed Description

Construct objects based on a specification array.

Contents of the specification array are as follows:

'factory' => callable,
'class' => string,

The specification array must contain either a 'class' key with string value that specifies the class name to instantiate or a 'factory' key with a callable (is_callable() === true). If both are passed, 'factory' takes precedence but an InvalidArgumentException will be thrown if the resulting object is not an instance of the named class.

'args' => array,
'closure_expansion' => bool, // default true
'spec_is_arg' => bool, // default false
'services' => (string|null)[], // default empty
'optional_services' => (string|null)[], // default empty

The 'args' key, if provided, specifies arguments to pass to the constructor/callable. Values in 'args' which are Closure instances will be expanded by invoking them with no arguments before passing the resulting value on to the constructor/callable. This can be used to pass live objects to the constructor/callable. This behavior can be suppressed by adding closure_expansion => false to the specification.

If 'spec_is_arg' => true is in the specification, 'args' is ignored. The entire spec array is passed to the constructor/callable instead.

If 'services' is supplied and non-empty (and a service container is available), the named services are requested from the PSR-11 service container and prepended before 'args'. null values in 'services' are passed to the constructor unchanged.

Optional services declared via 'optional_services' are handled the same, except that if the service is not available from the service container null is passed as a parameter instead. Optional services are appended directly after the normal required services.

If any extra arguments are passed in the options to getObjectFromSpec() or createObject(), these are prepended before the 'services' and 'args'.

'calls' => array

The specification may also contain a 'calls' key that describes method calls to make on the newly created object before returning it. This pattern is often known as "setter injection". The value of this key is expected to be an associative array with method names as keys and argument lists as values. The argument list will be expanded (or not) in the same way as the 'args' key for the main object.

Note these calls are not passed the extra arguments.

Constructor & Destructor Documentation

◆ __construct()

Wikimedia\ObjectFactory\ObjectFactory::__construct ( ContainerInterface  $serviceContainer)
Parameters
ContainerInterface$serviceContainerService container

Member Function Documentation

◆ createObject()

Wikimedia\ObjectFactory\ObjectFactory::createObject (   $spec,
array  $options = [] 
)

Instantiate an object based on a specification array.

This calls getObjectFromSpec(), with the ContainerInterface that was passed to the constructor passed as ‘$options['serviceContainer’]`.

@phan-template T @phpcs:disable Generic.Files.LineLength @phan-param class-string<T>|callable(mixed ...$args):T|array{class?:class-string<T>,factory?:callable(mixed ...$args):T,args?:array,services?:array<string|null>,optional_services?:array<string|null>,calls?:string[],closure_expansion?:bool,spec_is_arg?:bool} $spec @phan-param array{allowClassName?:bool,allowCallable?:bool,extraArgs?:array,assertClass?:string} $options @phpcs:enable @phan-return T|object

Parameters
array | string | callable$specSpecification array, or (when the respective $options flag is set) a class name or callable. Allowed fields (see class documentation for more details):
  • 'class': (string) Class of the object to create. If 'factory' is also specified, it will be used to validate the object.
  • 'factory': (callable) Factory method for creating the object.
  • 'args': (array) Arguments to pass to the constructor or the factory method.
  • 'services': (array of string/null) List of services to pass as arguments. Each name will be looked up in the container given to ObjectFactory in its constructor, and the results prepended to the argument list. Null values are passed unchanged.
  • 'optional_services': (array of string/null) Handled the same as services, but if the service is unavailable from the service container the parameter is set to 'null' instead of causing an error.
  • 'calls': (array) A list of calls to perform on the created object, for setter injection. Keys of the array are method names and values are argument lists (as arrays). These arguments are not affected by any of the other specification fields that manipulate constructor arguments.
  • 'closure_expansion': (bool, default true) Whether to expand (execute) closures in 'args'.
  • 'spec_is_arg': (bool, default false) When true, 'args' is ignored and the entire specification array is passed as an argument. One of 'class' and 'factory' is required.
array$optionsAllowed keys are
  • 'allowClassName': (bool) If set and truthy, $spec may be a string class name. In this case, it will be treated as if it were ‘[ 'class’ => $spec ]‘.
  • 'allowCallable’: (bool) If set and truthy, $spec may be a callable. In this case, it will be treated as if it were ‘[ 'factory’ => $spec ]‘.
  • 'extraArgs’: (array) Extra arguments to pass to the constructor/callable. These will come before services and normal args.
  • 'assertClass': (string) Throw an UnexpectedValueException if the spec does not create an object of this class.
Returns
object
Exceptions
InvalidArgumentExceptionwhen object specification is not valid.
UnexpectedValueExceptionwhen the factory returns a non-object, or the object is not an instance of the specified class.

◆ expandClosures()

static Wikimedia\ObjectFactory\ObjectFactory::expandClosures ( array  $list)
staticprotected

Iterate a list and call any closures it contains.

Parameters
array$listList of things
Returns
array List with any Closures replaced with their output

◆ getObjectFromSpec()

static Wikimedia\ObjectFactory\ObjectFactory::getObjectFromSpec (   $spec,
array  $options = [] 
)
static

Instantiate an object based on a specification array.

@phan-template T @phpcs:disable Generic.Files.LineLength @phan-param class-string<T>|callable(mixed ...$args):T|array{class?:class-string<T>,factory?:callable(mixed ...$args):T,args?:array,services?:array<string|null>,optional_services?:array<string|null>,calls?:string[],closure_expansion?:bool,spec_is_arg?:bool} $spec @phan-param array{allowClassName?:bool,allowCallable?:bool,extraArgs?:array,assertClass?:string,serviceContainer?:ContainerInterface} $options @phpcs:enable @phan-return T|object

Parameters
array | string | callable$specAs for createObject().
array$optionsAs for createObject(). Additionally:
  • 'serviceContainer': (ContainerInterface) PSR-11 service container to use to handle 'services'.
Returns
object
Exceptions
InvalidArgumentExceptionwhen object specification is not valid.
InvalidArgumentExceptionwhen $spec['services'] or $spec['optional_services'] is used without $options['serviceContainer'] being set and implementing ContainerInterface.
UnexpectedValueExceptionwhen the factory returns a non-object, or the object is not an instance of the specified class.

◆ validateSpec()

static Wikimedia\ObjectFactory\ObjectFactory::validateSpec (   $spec,
array  $options 
)
staticprotected

Convert a string or callable to a spec array.

Parameters
array | string | callable$specAs for createObject() or getObjectFromSpec()
array$optionsAs for createObject() or getObjectFromSpec()
Returns
array Specification array
Exceptions
InvalidArgumentExceptionwhen object specification does not contain 'class' or 'factory' keys

The documentation for this class was generated from the following file: