PHPackages                             ajaxray/magic - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. ajaxray/magic

ActiveLibrary

ajaxray/magic
=============

Simple Auto-wiring, PSR-11 compliant Dependency injection library for PHP 8.

v0.0.2(4y ago)27MITPHPPHP &gt;=8.0

Since Nov 1Pushed 4y ago2 watchersCompare

[ Source](https://github.com/ajaxray/magic)[ Packagist](https://packagist.org/packages/ajaxray/magic)[ RSS](/packages/ajaxray-magic/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (3)Versions (3)Used By (0)

Magic - tiny Dependency Injection Container for PHP 8
=====================================================

[](#magic---tiny-dependency-injection-container-for-php-8)

A tiny Dependency Injection Container for PHP 8 under 200 lines. Made for fun and exploring PHP Reflection features. But it does what it claims.

**Does it really work?**
Yes, it does! [Here](https://github.com/ajaxray/slim-magic) is a sample applocation with [Slim Framework](https://www.slimframework.com) using *Magic* as Dependency Injection Container.

Features
--------

[](#features)

- Compatible with [PSR-11: Container interface](https://www.php-fig.org/psr/psr-11/)
- Made for PHP8
- Service binding by Class, Interface or anonymous functions
- Resolve dependencies using:
    - Auto-wiring by class/interface name
    - Mapped Name/identifier of a service
    - Interface of the service
    - Implementation of the service
- Constructor DI capabilities based on Type-hinting
- Life-circle control of the objects (singleton / new instance per request)
- Easy to use with any framework (that usages PSR-11 compatible container) or even a plain php file
- [PSR-4 autoloading](https://www.php-fig.org/psr/psr-4/) compliant structure

*Caution: This library is still going through initial development phase!*

Installation
------------

[](#installation)

Just pull it in your project using composer.

```
composer require ajaxray/magic --with-all-dependencies
```

Or even you can [download](https://github.com/ajaxray/magic/archive/refs/heads/main.zip) it and include manually.

How to use
----------

[](#how-to-use)

### Basics

[](#basics)

First, make an instance of `Magic` and bind service class.

```
$magic = new Magic();
$magic->map('logger', MyLogger::class);
```

Now you can get instance of `MyLogger` using the service name `logger`.

```
$logger = $magic->get('logger');
$logger->info('Using Magic as dependency injection container');
```

If `MyLogger` constructor expects some arguments, `Magic` will try to instantiate and supply them too. See next section for more detail on arguments.

### Resolving service arguments

[](#resolving-service-arguments)

A service constructor may require some arguments to instantiate it. Container will try to supply them with different strategy based on argument type.

#### Object arguments

[](#object-arguments)

Type hint will be used to determine the type of object. Magic will try to instantiate the object arguments based on -

- If the name of parameter matches any defined service identifier. Type of object will be checked for safety.
- If any service defined with the Class/Interface name. Interface should be mapped to a concrete class in that case.
- Auto-wiring. Scalar parameters should be resolvable from container-wide defined parameters.

For example, let's think we have this constructor in a class -

```
public function __construct(\Doctrine\DBAL\Connection $dbConn)
```

The following definitions will be tried sequentially.
Based on name matching -

```
$container->map('dbConn', function($m, $params) {
    return \Doctrine\DBAL\DriverManager::getConnection(['url' => $params['dsn']]);
});
```

Based on Type matching -

```
$container->map(Connection::class, function($m, $params) {
    return \Doctrine\DBAL\DriverManager::getConnection(['url' => $params['dsn']]);
});
```

And finally, auto-wiring will be tried if none of the above definitions found.

#### Scalar arguments

[](#scalar-arguments)

You have to set the scalar arguments manually. Parameters can be set container-wide or during service definition.

Container-wide set parameters will be used for all service with the same argument name.

```
// e,g, new MyDbConnection($user, $password, $host = 'localhost', $port = 3306);
$magic->map('db', MyDbConnection::class);

$magic->param('host', 'theHostNameOrIP');
$magic->param('user', 'root');
$magic->param('password', 'TheSecret');

// parameters will be supplied by name matching automatically
$magic->get('db');
```

Service specific argument values can be supplied at the time of service binding. These params will be used with ONLY this specific service.

```
$magic->map('db', MyDbConnection::class, [
    'host' => 'theHostNameOrIP',
    'user' => 'root',
    'pass' => 'TheSecret',
]);
```

*Hint: Arguments can be specified from `.env` file from the coming release.*

### Auto-wiring

[](#auto-wiring)

In most of the cases, services can be loaded without binding anything if its dependencies (constructor params, if any) satisfies the following criteria:

- Scalar dependencies are resolvable from globally set parameters.
- Object/Interface dependencies are type hinted and auto-loadable,
- Object/Interface dependencies (and their dependencies) satisfies these prerequisites of Auto-wiring or explicitly mapped

```
$magic = new Magic();
$magic->get(MyDbConnection::class);
```

### Interface Binding

[](#interface-binding)

You can bind an interface as a service. In this case, you have to map the interface with an implementation to be instantiated.

```
$magic->map('notifier', NotifierInterface::class, ['receiver' => 'receiver@xyz.tld']);
$magic->mapInterface(NotifierInterface::class, MailNotification::class);

$magic->get('notifier')->notify('The message to send');
```

### Binding using anonymous function

[](#binding-using-anonymous-function)

You can bind service with Pimple/Laravel style anonymous functions. The function will receive an instance of container and parameters array.

```
// Simple
$magic->map('greeter', fn($m, $params) => new Greeter($params['name']), ['name' => 'ajaxray']);

// Complex
$magic->param('user', 'sysadmin');
$magic->param('pass', 'TheSecret');

$magic->map('mailer', function ($m, $params) {
        $transport = (new Swift_SmtpTransport($params['smtp.host'], 25))
            ->setUsername($params['user'])
            ->setPassword($params['pass'])
        ;

        return new Swift_Mailer($transport);
    }, ['smtp.host' => 'smtp.example.tld']);
```

In the above example, `user` and `pass` will be resolved from globally set params. That means, the globally set params will be merged with the service specific params while resolving or passing to service binding functions.

### Service life cycle (singleton or factory)

[](#service-life-cycle-singleton-or-factory)

By default, if a service is instantiated once, it will be reused for subsequent `get()` calls or resolving other constructor parameters. But you can disable this behaviour by passing `@cacheable` parameter.

```
$magic->map('dbMapper', ActiveRecord::class, ['@cacheable' => false]);

// dbMapper will not be cached and will return new instance for every get() call
$aUser = $magic->get('dbMapper')->load('User', 3);
$otherUser = $magic->get('dbMapper')->load('User', 26);
```

Testdox
-------

[](#testdox)

```
PHPUnit 9.5.10 by Sebastian Bergmann and contributors.

Auto Wiring (Ajaxray\Test\AutoWiring)
 ✔ Resolve class by name without constructor
 ✔ Resolve class by name with scalar param constructor
 ✔ Resolve class by name with object param constructor

Basic Class (Ajaxray\Test\BasicClass)
 ✔ Service mapping without constructor
 ✔ Service mapping with scalar param constructor
 ✔ Service mapping with object param constructor

Object Chaining (Ajaxray\Test\ObjectChaining)
 ✔ Resolve classes in chained object graph

Object Lifecycle (Ajaxray\Test\ObjectLifecycle)
 ✔ Provides same instance for multiple get call by default
 ✔ Provides same instance for multiple get call of interface
 ✔ Provides same instance for multiple get call of callback binding
 ✔ Service caching can be disabled for class mapping
 ✔ Service caching can be disabled for interface
 ✔ Service caching can be disabled for callback binding

Resolve Interface (Ajaxray\Test\ResolveInterface)
 ✔ Service loading by interface if single implementation
 ✔ Resolve interface type hint to implementation if single implementation
 ✔ Service loading by mapped interface
 ✔ Resolve mapped interface type hint to implementation

Service Binding By Callable (Ajaxray\Test\ServiceBindingByCallable)
 ✔ Service mapping without constructor
 ✔ Service mapping with scalar param constructor
 ✔ Service mapping with object param constructor
 ✔ Callable can serve non object types

Time: 00:00.015, Memory: 6.00 MB

OK (21 tests, 23 assertions)

```

###  Health Score

22

—

LowBetter than 22% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

2

Last Release

1653d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2d53da7c0bace1db3c303d2c105fdf270d5fad970432c6dd702d9e23ea62ab86?d=identicon)[ajaxray](/maintainers/ajaxray)

---

Top Contributors

[![ajaxray](https://avatars.githubusercontent.com/u/439612?v=4)](https://github.com/ajaxray "ajaxray (13 commits)")

---

Tags

phpdependencydependency injection containerphp-di

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/ajaxray-magic/health.svg)

```
[![Health](https://phpackages.com/badges/ajaxray-magic/health.svg)](https://phpackages.com/packages/ajaxray-magic)
```

###  Alternatives

[infocyph/intermix

A Collection of useful PHP class functions.

136.4k1](/packages/infocyph-intermix)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
