PHPackages                             php-partial-constructor/php-partial-constructor - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. php-partial-constructor/php-partial-constructor

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

php-partial-constructor/php-partial-constructor
===============================================

Partial constructor application.

355PHP

Since Aug 22Pushed 12y agoCompare

[ Source](https://github.com/rubendg/php-partial-constructor)[ Packagist](https://packagist.org/packages/php-partial-constructor/php-partial-constructor)[ RSS](/packages/php-partial-constructor-php-partial-constructor/feed)WikiDiscussions master Synced 4w ago

READMEChangelogDependenciesVersions (1)Used By (0)

Schönfinkelize your constructor - partial constructor application for PHP
=========================================================================

[](#schönfinkelize-your-constructor---partial-constructor-application-for-php)

[![Build Status](https://camo.githubusercontent.com/eea371eed254e4b847166ba8d0bac6c96cafb7fb63d950e105ba531862461783/68747470733a2f2f6170692e7472617669732d63692e6f72672f727562656e64672f7068702d7061727469616c2d636f6e7374727563746f722e706e673f6272616e63683d6d6173746572)](http://travis-ci.org/rubendg/php-partial-constructor)

A library for partially applying object constructors. Instead of providing all constructor arguments it puts you in control over *when* you provide *which* constructor arguments.

Install using Composer:

```
php composer.phar require php-partial-constructor/php-partial-constructor:dev-master

php composer.phar update
```

A quick example. Suppose you have a class *Foo*:

```
class Foo {
   public function __construct(A $a, B $b) {}
}
```

and you want to provide *A*, but provide *B* at a later moment. Normally this would not be possible, and one has to reach to other means like using a setter:

```
class Foo {
   public function __construct(A $a) {}

   public function setB(B $b) {}
}
```

This would however imply that every method relying on the presence of *B* will need an additional consistency check. If *B* really is an integral part of what it means to be a *Foo* it should belong in the constructor, not in a setter [see](http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)).

Using the library it is possible to maintain the previous design with a little extra help:

```
$foo = new Foo_;

$fooWithA = $foo->apply(['a' => new A]);
```

Note that we did not create an instance of *Foo* but of *Foo\_*. *Foo\_* acts as a wrapper around the construction process of *Foo*. Using its *apply*method you can provide *Foo's* constructor arguments as an array. If all arguments are provided you get an instance of *Foo*. Otherwise you will get a *new* instance of *Foo\_* that still needs some parameters in order to become a *Foo*.

*Foo\_*'s definition is quite easy:

```
class Foo_ implements \ArrayAccess {
   use Schoenfinkel\Schoenfinkelize;
   protected static $targetClassName = 'Foo';
}
```

All you have to do is let "$targetClassName\* point to *Foo*. The rest is handled by the *Schoenfinkelize* trait.

Obviously creating such companion classes quickly becomes tiresome. Luckily you can get rid of the manual boilerplate by generating the classes on the fly.

If you are in a [Composer](http://getcomposer.org/) project all you have to do is create your own "autoload.php" file adapting the one generated by Composer:

```
use \Schoenfinkel\Integration\CodeGenerator;
use \Schoenfinkel\Integration\PostfixClassNameMapping;
use \Schoenfinkel\Integration\ClassLoader\SchoenfinkelClassLoader;

$loader = require __DIR__ . '/../vendor/autoload.php';
$custom = new SchoenfinkelClassLoader($loader, new CodeGenerator(new PostfixClassNameMapping()));
$loader->unregister();
spl_autoload_register(array($custom, 'loadClass'));
```

By default classes which have an underscore at the end will be treated as classes that can have their constructor partially applied. The class name without the underscore will become the target class name. Of course you can change this behavior to your own liking by either setting a different postfix on the *PostfixClassNameMapping* or implement your own *ClassNameMapping*.

Note that currently the implementation uses *eval* for bringing the generated code into scope. This may be a problem for you if you have disabled *eval* in the [disabled\_functions](http://php.net/manual/en/ini.core.php#ini.disable-functions) directive.

To sum up some of the libraries' advantages:

- For simple cases replaces to need for applying the [builder pattern](http://en.wikipedia.org/wiki/Builder_pattern)
- No more setters for attributes that should be provided in the constructor
- Type hinting support for partially constructed classes (albeit of minimal expressiveness, see below)
- Until all parameters are provided every parameter can accessed by name and or overwritten
- Partially applied objects can be passed around like ordinary classes
- Independent of dependency injection framework
- Type hints of target class are checked during parameter application ([fail-fast](http://en.wikipedia.org/wiki/Fail-fast))
- The library also plays nice with [Symfony DIC](http://symfony.com/blog/symfony-components-the-dependency-injection-container). A subset of the actual constructor parameters can be passed directly into the partial constructor:

```

```

Disadvantages:

- Induces a slight performance overhead.

```
./vendor/bin/phpunit test/performance/PerformanceTest.php
```

Shows that plain object construction is about 24 times faster.

- Does not work for constructors that take a variable amount of arguments (using func\_get\_args())
- Default and optional arguments are currently treated as regular (required) arguments.
- Currently a partially constructed class still expecting 1 parameter cannot be distinguished in its type from the same partially constructed class expecting any other number of parameters.

Future:

- Maybe provide class generation based on PHP annotations @Curried
- Maybe replace *eval* with something like this:
- Reflect the number of expected parameters in the type of a partially constructed class.

Related:

- Constructor currying with Google Guice: [http://slesinsky.org/brian/code/guice\_with\_curry.html](http://slesinsky.org/brian/code/guice_with_curry.html)
- PHP function currying:
- PHP functional prelude:
- Currying vs partial application:
- Currying vs partial function application in C#: [http://msmvps.com/blogs/jon\_skeet/archive/2012/01/30/currying-vs-partial-function-application.aspx](http://msmvps.com/blogs/jon_skeet/archive/2012/01/30/currying-vs-partial-function-application.aspx)

###  Health Score

22

—

LowBetter than 21% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity41

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.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/439057?v=4)[rubendg](/maintainers/rubendg)[@rubendg](https://github.com/rubendg)

---

Top Contributors

[![rubendg](https://avatars.githubusercontent.com/u/439057?v=4)](https://github.com/rubendg "rubendg (35 commits)")

### Embed Badge

![Health badge](/badges/php-partial-constructor-php-partial-constructor/health.svg)

```
[![Health](https://phpackages.com/badges/php-partial-constructor-php-partial-constructor/health.svg)](https://phpackages.com/packages/php-partial-constructor-php-partial-constructor)
```

PHPackages © 2026

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