PHPackages                             pyrsmk/chernozem - 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. [PSR &amp; Standards](/categories/psr-standards)
4. /
5. pyrsmk/chernozem

AbandonedArchivedLibrary[PSR &amp; Standards](/categories/psr-standards)

pyrsmk/chernozem
================

Dependency injection container for the masses

4.2.1(6y ago)1599816MITPHPPHP &gt;=5.4

Since Feb 25Pushed 6y ago1 watchersCompare

[ Source](https://github.com/pyrsmk/Chernozem)[ Packagist](https://packagist.org/packages/pyrsmk/chernozem)[ RSS](/packages/pyrsmk-chernozem/feed)WikiDiscussions master Synced 2w ago

READMEChangelog (1)Dependencies (1)Versions (18)Used By (6)

Chernozem 4.2.1
===============

[](#chernozem-421)

Chernozem is an advanced dependency injection container based on `ArrayAccess`. It has been primarily designed to be extended by another class, so it takes care of any option for you. But it can also be used as a simple container.

Concretely, Chernozem can register any value you want and create services. Services are simple closures, used to initialize objects and return their instance. It's really useful for, per example, loading a logger when we need it, with all required options and dependencies it could need.

If you want to learn more about dependency injection, Fabien Potencier has written an article about that : .

Features
--------

[](#features)

- interoperability with [container-interop](https://github.com/container-interop/container-interop)
- factory closures
- inflectors
- delegate containers
- service providers
- type hinting
- and more...

Note about the v4
-----------------

[](#note-about-the-v4)

Chernozem has been completely rewritten and the API has changed. Please read the whole documentation before upgrading from v3.

Installing
----------

[](#installing)

```
composer require pyrsmk/chernozem

```

Basics
------

[](#basics)

Let's see quickly how it works :

```
$chernozem = new Chernozem\Container();

// Set a value
$chernozem['foo'] = 72;

// Get a value
echo $chernozem['foo'];

// Test a value
if(isset($chernozem['foo'])) {
	// 'foo' value exists
}

// Remove a value
unset($chernozem['foo']);
```

Alternatively, and for interoperability, you can access to Chernozem with this API :

```
// Set a value
$chernozem->set('foo', 72);

// Get a value
echo $chernozem->get('foo');

// Test a value
if($chernozem->has('foo')) {
	// 'foo' value exists
}

// Remove a value
$chernozem->remove('foo');
```

Or also with this API :

```
// Set a value
$chernozem->setFoo(72);

// Get a value
echo $chernozem->getFoo();
```

You can instantiate Chernozem with some values too :

```
$chernozem = new Chernozem\Container([
	'foo' => 72,
	'bar' => 33
]);
```

You can add values to the container without specifying keys (like with a normal array) :

```
$chernozem[] = 'foo';
```

Chernozem also supports objects as keys :

```
$myclass = new Stdclass();
$chernozem[$myclass] = 72;
// Print '72'
echo $chernozem[$myclass];
```

If you need to clear all your container values, do :

```
$chernozem->clear();
```

Factory closures
----------------

[](#factory-closures)

With factory closures you can create services. The `factory()` method creates a service that will always return a new instance of the service :

```
$chernozem['some_service'] = $chernozem->factory(function($chernozem) {
	return new Some_Service();
});
```

The `service()` method creates a service that will return the same instance of itself :

```
$chernozem['some_service'] = $chernozem->service(function($chernozem) {
	return new Some_Service();
});
```

Service providers
-----------------

[](#service-providers)

Service providers are a way to organize and reuse your services with classes. Let's see how we write a service provider :

```
class MyService implements Chernozem\ServiceProviderInterface {

	public function register(Interop\Container\ContainerInterface $container) {
		$container['some_service1'] = new Some_Service();
		$container['some_service2'] = new Another_Service();
		$container['an_option'] = 'my@email.com';
	}

}
```

Service providers are run directly when they are registered, with :

```
$chernozem->register(new MyService());
```

Type hinting
------------

[](#type-hinting)

Type hinting is a cool feature of Chernozem that let you define the type of a value in the container. It avoids issues in your application because it could happen that a wrong type is set.

```
// Set a list of fruits
$chernozem['fruits'] = ['apple', 'banana', 'pear'];
// Set type hinting
$chernozem->hint('fruits', 'array');
// Oops! Wrong type!
$chernozem['fruits'] = 72;
```

The following basic types are supported :

- boolean/bool
- integer/int
- float/double
- string
- array
- any class name

Read only values
----------------

[](#read-only-values)

You can mark your values as read only if needed with :

```
// Set a 'mailer' service
$chernozem['mailer'] = $chernozem->service(function($chernozem) {
	return new Mailer();
});
// Mark as read onyl
$chernozem->readonly('mailer');
```

Inflectors
----------

[](#inflectors)

All previous features are available thanks to inflectors. Inflectors are a way to alter a value when it's set or got. Note that setter inflectors are usually used for data validation, and getter inflectors for data filtering. For the next example, let's say we have previously set some random service that we don't want to be overwritten further in our application, and we want to run some actions each time the service is retrieved :

```
$chernozem->setter('foo_service', function($service) {
	throw new Exception("'foo_service' is already set!");
	return $service; // Never run, it's only for the example
});

$chernozem->getter('foo_service', function($service) {
	$service->executeSomeAction();
	$service->executeAnotherAction();
	return $service;
});
```

Now, setting 'foo\_service' will throw an exception and each time 'foo\_service' is retrieved, two actions will be run on our service. It's that simple!

Delegate and composite container
--------------------------------

[](#delegate-and-composite-container)

A delegate container is a container that will be used to load dependencies for services. You may see that `factory()` and `service()` pass Chernozem as parameter. It's used for the service to load some dependencies on the container. But in big applications, you could deal with many different containers and your dependencies could be on another container than Chernozem.

```
$delegate_container = new SomeVendor\Container();

// ... some stuff ...

$chernozem->delegate($delegate_container);

$chernozem['some_service'] = $chernozem->service(function($delegate_container) {
	$some_service = new Some_Service();
	// Load an option that is registered in the delegate container
	$some_service->setOption('some_option', $delegate_container->get('some_option'));
	return $some_service;
});
```

If you have a lot of containers to manage,, Chernozem has a `Composite` class to take care of that :

```
// Instantiate containers
$container1 = new SomeVendor\Container();
$container2 = new AnotherVendor\Container();

// ... some stuff ...

// Add containers to the composite container
$composite = new Chernozem\Composite();
$composite->add($container1);
$composite->add($container2);
```

Now that all your containers are registered, you can get a value as always :

```
echo $composite['foo'];
```

Calling `foo` on the composite class will get the first `foo` value found in the registered containers. You can verify if a key exist too :

```
if(isset($composite['foo'])){
	// the 'foo' key exists
}
```

Note that the `Composite` class is based on [container-interop](https://github.com/container-interop/container-interop), and it also supports a `delegate()` method so you can chain things, if needed.

Loops
-----

[](#loops)

Chernozem container also implements `Iterator` and `Countable`. That means that you can iterate over the container and count how many elements are in it.

```
echo count($chernozem);
```

```
foreach($chernozem as $id => $value) {
	var_dump($value);
}
```

Alternative ways to get data
----------------------------

[](#alternative-ways-to-get-data)

You can retrieve all container values with :

```
$values = $chernozem->toArray();
```

If you need to get a raw value that has not been modified by inflectors, like the base closure of a service, call `raw()` :

```
$chernozem['some_service'] = $chernozem->service(function($c) {
	// do stuff
});

$closure = $chernozem->raw('some_service');
```

Chaining arrays
---------------

[](#chaining-arrays)

You can't chain arrays to modify or retrieve a value with Chernozem, this is due to a PHP limitation with `ArrayAccess`. The basic way to handle this case is :

```
// Get 'foo' array
$foo = $chernozem['foo'];
// Add 'bar' value to the array
$foo['bar'] = 42;
// Update 'foo' value
$chernozem['foo'] = $foo;
```

But to simplify this, you can declare a `Chernozem\Container` object instead of an array as your container value, then you'll be able to chain things :

```
$chernozem['foo'] = new Chernozem\Container(['bar' => 72]);
// Print '72'
echo $chernozem['foo']['bar'];
$chernozem['foo']['bar'] = 42;
// Print '42'
echo $chernozem['foo']['bar'];
```

Last notes
----------

[](#last-notes)

If you want to overwrite a factory closure (created with `factory()` or `service()`), you must unset the value before setting it :

```
$chernozem['service'] = $chernozem->service(function() {
	// First service
});

unset($chernozem['service']);

$chernozem['service'] = $chernozem->service(function() {
	// New service
});
```

License
-------

[](#license)

Chernozem is published under the [MIT license](http://dreamysource.mit-license.org).

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity22

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity67

Established project with proven stability

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 ~144 days

Recently: every ~360 days

Total

17

Last Release

2200d ago

Major Versions

3.0.9 → 4.0.02016-07-01

PHP version history (2 changes)3.0.0PHP &gt;=5.3.0

4.0.0PHP &gt;=5.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/7f97d81cfd6d30587cdae24925bc0899331394d723d04ee4b76eb9435a565fe9?d=identicon)[pyrsmk](/maintainers/pyrsmk)

---

Tags

containerdependencyinjection

### Embed Badge

![Health badge](/badges/pyrsmk-chernozem/health.svg)

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

###  Alternatives

[league/container

A fast and intuitive dependency injection container.

86892.2M397](/packages/league-container)[capsule/di

A PSR-11 compliant autowiring dependency injection container.

2859.2k2](/packages/capsule-di)[miladrahimi/phpcontainer

Dependency injection (IoC) container for PHP projects

1323.5k2](/packages/miladrahimi-phpcontainer)

PHPackages © 2026

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