Functional PHP Preprocessor - Generate Immutable Data Types
Switch branches/tags
Nothing to show
Clone or download
prolic Merge pull request #94 from SimonPrins/master
Changed text of error message to make it more clear that the argument…
Latest commit 72e2ac7 Oct 19, 2018


Functional PHP Preprocessor - Immutable data type generator

What it this?

This library can generate immutable data types based on fpp definitions, the syntax is inspired by Haskell.

YouTube Video Tutorial

YouTube Video Tutorial


See the docs here

So what really is it?

Create a file and put this in it:

namespace Model\Foo;

data Person = Person { string $name, ?int $age };

This will generate the following php code:

namespace Model\Foo;
final class Person
    private $name;
    private $age;

    public function __construct(string $name, ?int $age)
        $this->name = $name;
        $this->age = $age;

    public function name(): string
        return $this->name;

    public function age(): ?int
        return $this->age;

    public function withName(string $name): Person
        return new self($name, $this->age);

    public function withAge(?int $age): Person
        return new self($this->name, $age);


No problem

namespace MyEnum;

data Color = Red | Blue | Green | Yellow deriving (Enum);
$blue = Color::blue();
var_dump($blue->equals(Color::blue())); // true
var_dump($blue->equals(Color::red())); // false

function (MyEnum\Color $color): string
    return $color->value();

Enums with value mappings

namespace MyEnum;

data Color = Red | Blue deriving (Enum) with (Red:'someThing', Blue: 13);
var_dump(Color::red()->value()); // 'someThing'
var_dump(Color::blue()->value()); // 13


Derivings are kind of PHP's extends keyword, the following rules apply:

  • It's possible to derive multiple times
  • Some derivings are not compatible to each other (f.e. Command and ToArray cannot be mixed)

There are 14 deriving types for now:

  • AggregateChanged
  • Command
  • DomainEvent
  • Enum
  • Equals
  • FromArray
  • FromScalar
  • FromString
  • Query
  • MicroAggregateChanged (not extending from prooph/eventsourcing, f.e. for prooph/micro)
  • ToArray
  • ToScalar
  • ToString
  • Uuid

Deriving Equals + ToArray

namespace Model\Foo;

data Person = Person { string $name, ?int $age } deriving (ToArray, Equals);

Now you can do this:

$p = new Model\Foo\Person(['name' => 'sasa', 'age' => 36]);
var_dump($p->toArray()); // ['name' => 'sasa', 'age' => 36]
$p->equals($p) // true


You can add additional conditions to your code:

namespace Foo;
data FirstName = String deriving (FromString, ToString);
data LastName = String  deriving (FromString, ToString);
data Age = Int deriving (FromScalar, ToScalar);
data Person = Person { FirstName $firstName, LastName $lastName, Age $age } | Boss { FirstName $firstName, LastName $lastName } where
        | strlen($lastName->toString()) === 0 => 'last name too short'
        | $age->toScalar() < 18 => "you\'re too young, sorry"
        | strlen($lastName->toString()) < 5 => 'last name too short'
        | strlen($firstName->toString()) === 0 => 'first name too short';


php bin/fpp.php <source dir or file>

It will try to find your composer autoload and fetch psr-4 and psr-0 prefixes from it. You'll get an exception, if you want to dump a class, where you have no composer autoload definition.


  • Create immutable data types with ease
  • Strict types always
  • Generate prooph commands
  • Generate prooph events
  • Generate prooph queries
  • Generate prooph aggregate changed events
  • Ability to switch dumper implementation for custom output
  • Allow composite data objects
  • Allow composite prooph objects
  • Constructor validation
  • Allow creating of custom constructors
  • Dump files according to psr-4 and psr-0 autoloading rules
  • Array notation for objects and scalar types
  • Enum value mappings
  • Support for conditions