Download the PHP package innmind/compose without Composer

On this page you can find all versions of the php package innmind/compose. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package compose

Compose

master develop
Scrutinizer Code Quality Scrutinizer Code Quality
Code Coverage Code Coverage
Build Status Build Status

Compose is dependency injection container. It is born out of the recurring problem that many libraries need a complex initialisation of objects in order to work. The usual approach is to build a dedicated bundle when you use Symfony, or the equivalent for other frameworks, but this can lead with the bundle being out of sync with the library. It leads to extra work to apply the changes of the library back to the bundle. And this should be done for every framework you want to support, which can be tedious. All of this to provide an easy way for the end user of the library to use it.

The second reason that have motivated this library is the way all the existing (that I'm aware of) dependency injection containers use a shared global state, meaning the initialisation of all dependencies/libraries are in the same container. This means that if you're not careful you can easily end up coupling libraries by accessing objects from different libraries that should not be exposed. Since the containers doesn't explicitly say which services you can access, you can end up doint it without realising it. The end problem being that an update of the library can break your app because you rely on private stuff.

With all of this in mind, Compose has been built with these principles:

Note: Compose implements the PSR-11 interface

Installation

Usage

The first part is defining the services. For the moment the only way is via a yaml file.

Example:

And then build the container:

This is a dummy exmaple to describe all the main parts of the container definition. The only 2 required keys here are services and expose.

The services key will contain all the definitions to build your objects. The definitions can be nested inside sub arrays, without depth limit, (like below) but the deepest array must nbe a service definition (otherwise the container will complain).

The expose key explicit the services you allow to expose to the outside world, with keys being the name you expose to the world and values being the references to the services definition described below it.

The arguments key is the implementation of the function principle (described above). It explicit the arguments you need to provide when building the library. For each argument you need to tell the type you expect, you can use:

Note: you can create your own types, see the loader.

For each type you can prefix it by ? meaning it is optional. So if you do not provide it when building the container it will resolve to null. Or you can specify the argument to resolve to a default value then you can use the syntax {type} ?? ${reference}, where reference is the name of one of the services you've defined.

Finally, the dependencies key shouldn't be used when defining the container for a library, but only when defining your app. It should be used in case of an app as it is at this final level where you can have cross dependencies between the libraries you want to use. Each key/value pair defined under a dependency are the arguments provided to the sub container. The path provided for the dependency is relative to your definition path, check the tests to have concrete examples. You can also use the syntax @{vendor}/{package}/path/to/container.yml that will resolve to the path to a composer package.

Reference system

In order to reference a service or an argument you use the syntax ${service_or_argument_name}, however not everything is accessible for everywhere. Allowed references:

Services

Constructors

A service definition must always follow the pattern {name} {constructor} where the constructor part most of the time will be a class name, but your not limited to that. Here are all the constructor patterns:

Note: map, set and stream are structures that lazy load the services (if coming from one of your definitions) injected into them, meaning those services will be instantiated only upon the first manipulation of the structure. This is done so you can easily build an event listener, command bus (or other) without injecting the full container in those services.

Note: you can create your own constructors, see the loader.

Arguments

Full list of argument patterns you can use:

Note: you can create your own argument patterns, see the loader.

Stacks

Composition is a great way to extend the behaviour for an implementation of a given interface, Compose ease this behaviours via the stack constructor. Here's an example for a command bus:

Here we create a command bus equivalent to queueable(logger(default)). This is allowed thanks to the @decorated argument instructing which argument to replace when building the stack.

Important: obviously you cannot instantiate directly a service definition that have a @decorated argument.

To ease composition accross dependencies you can also expose a service definition that must be used in a stack. For example you can do the following (in case the services above are exposed):

This way you can define a service in you library that can go in a stack and have private dependencies related to your library and still use it in an application without revealing its inner working.

Compilation

Since parsing definition files and resolving all the references can quickly become complex, it can have a performance impact on your application. That's why you can compile the container to raw PHP. You can do it like so:

This will build a compiled container to raw PHP on first call and then will always reuse its cache. But when your developing you want your cache to be updated each time you update your services definition, to do that replace new Cache($path, $loader) by Cache::onChange($path, $loader).

Developer experience

When working on a large app it becomes near impossible to have the whole dependency graph in mind, to easily fix this is to have a visual representation of the dependencies. That's why Compose comes with a CLI tool (bin/compose) to help dump your services as a Graphviz representation.

bin/compose visualize definition.yml will print the dot file for your services, you can add the option -o graph.svg so it directly call graphviz to build the svg file (you can use any format supported by graphviz).

When actively building your services definition you can use bin/compose watch definition.yml graph.svg so the graph file is rebuilt each time you hit the save button.

Here's an example of the amqp.yml file:

Green homes are the services exposed, in blue are the arguments and in orange are the exposed services of your dependencies.


All versions of compose with dependencies

PHP Build Version
Package Version
Requires php Version ~7.2
innmind/immutable Version ~2.7
symfony/yaml Version ~3.0|~4.0
psr/container Version ^1.0
symfony/options-resolver Version ~3.0|^4.0
innmind/url Version ^2.0
innmind/url-resolver Version ^3.0
symfony/config Version ~3.0|^4.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package innmind/compose contains the following files

Loading the files please wait ....