Download the PHP package tflori/dependency-injector without Composer

On this page you can find all versions of the php package tflori/dependency-injector. 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 dependency-injector

Dependency Injector

.github/workflows/push.yml Test Coverage Maintainability Latest Stable Version Total Downloads License

A simple and lightweight dependency injector. Compatible to php standard recommendation for dependency injection containers (PSR-11).

What Is A Dependency

Something that your application needs to work correct. For example an instance of Calculator or Config or an object that implements CacheInterface.

Basic Usage

One of the biggest problems in software development is the tight coupling of dependencies. Imagine a class that creates an instance from DatabaseConnection with new DatabaseConnection(). This is called a tight coupling - it is so tight that you would have to overwrite your autoloader (what is not always possible) to mock the database connection.

There are two solutions to test this class without the need to have a database connection during the tests.

Passing The Dependency

When creating an object of that class you can provide the DatabaseConnection to the constructor. For example new MyService(new DatabaseConnection). In the tests you can then pass a mock new MyService(m::mock(DatabaseConnection::class)).

That would mean that everywhere in your application where you create an object of this class you have to know where your DatabaseConnection object is stored or create a new one. It's even more worse: when the interface for the class changes (for example an additional dependency get added) you will have to change this everywhere in your code.

Here comes the dependency injection into play. Here with the most strait forward and understandable way (a callback):

Make The Container Available

The container could also be available from within the class *1. This library provides a class with only static methods DI to make the dependencies available from everywhere. It is using the same interface but with static calls. The above example could look like this:

Tests

Now when we want to test the class we can just replace the dependency for database connection:

This works in both versions *2 and can safely be used for testing.

We are using here the static methods from DI in the rest of the document.

Advanced Usage

We can not only store callbacks that are executed when a new instance is required. There are some other practical ways that makes it easier for you to define how dependencies should be resolved.

Make An Object

With version 2.1 comes the new method DI::make(string $class, ...$args) which allows you to directly get an instance of $class with $args as constructor arguments without defining a dependency for it.

Even if the above examples are equal the method has a big advantage: you can provide a mock for the class.

Define Instances

Instances can be defined to be returned when a dependency is requested. Keep in mind that you will have to instantiate a class before using it what might have an impact in performance. Anyway this gives you an opportunity to also define several values for example a very simple configuration:

Do not misuse this as a global storage. You will get naming conflicts and we will not provide solutions for it.

Define Aliases

Aliases allow you to have several names for a dependency. First define the dependency and than alias it:

Define Dependencies

Dependencies that are built when they are requested can be added using Container::add(string $name, $getter). The getter can be a callable (such as closures - what we did above), a class name of a factory, an instance of a factory or any other class name.

Factory here means a class that implements FactoryInterface or SharableFactoryInterface.

Container:add() will return the factory that got added and which factory get added is defined as:

Dependencies using factories implementing SharableFactoryInterface can be shared by calling $factory->share() or using the shortcut Container::share(string $name, $getter).

Class Factory

The ClassFactory creates only an instance without any arguments by default. It also allows to pass different arguments to the constructor and that is the usual way suggested from PSR-11:

It is also possible to call methods on the new instance:

Non shared classes allow to pass additional arguments to the constructor:

Pattern Factory

A PatternFactory is a factory that can be used for different names. Keep in mind that when ever a dependency is requested and no other factory is defined for this dependency all pattern factories are requested to match against the requested name.

Namespace Factory

An example for a PatternFactory is the NamespaceFactory. The namespace factory can be used to load all classes of a previously defined namespace with this factory. Similar to the class factory it supports passing arguments and method calls after the request.

This example shows a factory definition for Controller classes:

A shared namespace factory stores the instance per class:

Singleton Factory

The SingletonFactory is a special factory that just wraps the call to ::getInstance(). The advantage here is that you don't have to create the instance if you don't need to or create a mock object for tests. Without this factory you can either pass an instance of the class or stick with the call to ::getInstance() in your code.

This factory also allows pass arguments to the ::getInstance() method for classes that store different instances for specific arguments.

Callable Factory

This factory is just calling the passed callback. The callback only have to be callable what is checked with is_callable($getter) - so you can also pass an array with class or instance and method name.

Because the callback could also be a static method from a class with [Calculator::class, 'getInstance']. It is also possible to use this for Singleton classes. The difference is that this could be shared but the SingletonFactory always calls ::getInstance() what is the preferred method from our point of view.

Own factories

When you write own factories you will have to implement FactoryInterface or SharableFactoryInterface. The AbstractFactory implements SharableFactoryInterface and can be extended to your needs in a very simple way:

Factories can be defined for dependencies using Container::add() or Container::share() as described above. But you can also register the namespace where your factories are defined and the container will try to find the factory for the requested dependency. When you request a dependency and it is not already defined it will check each registered namespace for a class named $namespace . '\\' . ucfirst($dependency) . $suffix.

Examples

Here are some small examples how you could use this library.

The Configuration

The Database Connection

The problem before: you can not mock the static function MyApp::getDatabaseConnection(). You also can not mock the static function DI::get('database'). But you can set the dependency to return a mock object:

Tips

Extend The DI Class

When you are using the DI class it makes sense to extend this class and add annotations for the __callStatic() getter so that your IDE knows what comes back from your DI:

Extend The Container Class

Similar functionality exists for Container. The magic method __isset() aliases Container::has(), __get() aliases Container::get($name) and __call() aliases Container::get($name, ...$args). So you can annotate your container like this:

Comments


All versions of dependency-injector with dependencies

PHP Build Version
Package Version
Requires php Version ^7.0 || ^8.0
psr/container Version ^1.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 tflori/dependency-injector contains the following files

Loading the files please wait ....