Loïc Faugeron Technical Blog

Memio models 15/04/2015

TL;DR: Describe code by building models.

Memio is a highly opinionated PHP code generation library, its version 1.0.0 (stable) is going to be released soon: currently the main package memio/memio is being split into smaller packages.

In this article, we'll have a look at the very first package to be ready: memio/model.

Describing code

Let's have a look at the following method:

    public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true)
    {
    }

We have many things here:

It has the following arguments:

Memio provides models that allow us to describe this method by constructing objects:

<?php

use Memio\Model\Argument;
use Memio\Model\Method;

require __DIR__.'/vendor/autoload.php';

$method = Method::make('handle')
    ->addArgument(Argument::make('Request', 'request'))
    ->addArgument(Argument::make('int', 'type')
        ->setDefaultValue('self::MASTER_REQUEST')
    )
    ->addArgument(Argument::make('bool', 'catch')
        ->setDefaultValue('true')
    )
;

Note: Static constructors are used to allow fluent interface (chaining calls). From PHP 5.6 it is possible to do the following: (new Method('handle'))->addArgument(new Argument('Request', 'request'));

Building models dynamically

Usually models aren't built manually, they could be constructed using:

Here's a usage example. When running the test suite, phpspec generates missing methods in our code (amongst many other nice things).

If the following call is found in a test:

        $this->handle($request);

And if the handle method isn't defined in the class currently tested, then phpspec gathers the following parameters:

Let's re-write its generator using Memio:

<?php

use Memio\Model\Argument;
use Memio\Model\Method;

require __DIR__.'/vendor/autoload.php';

function phpspec_generator($methodName, array $arguments) {
    $method = new Method($methodName);
    $index = 1;
    foreach ($arguments as $argument) {
        $type = is_object($argument) ? get_class($argument) : gettype($argument);
        $argumentName = 'argument'.$index++;
        $method->addArgument(new Argument($type, $argumentName));
    }

    return $method
}

Pretty straightforward!

Conclusion

Models are Memio's core, almost every memio packages will rely on them:

For now they can describe:

There are some limitations:

For now, it will be sufficient to start working on exciting projects!

If you'd like to find out more about Memio Models, have a look at the documentation: