Welcome to Abdul Malik Ikhsan's Blog

Getting Closer with Penny – A PHP Framework

Posted in Tutorial PHP by samsonasik on September 8, 2015

“One penny is valueless but a lot of pennies build an empire.”. This is a tagline that we can see at the Penny repository. Gianluca Arbezzano, A PHP developer that created it focused on creating interoperability concept. It uses great PHP components in the Framework.

There are PHP components that used in Penny Framework:
* nikic/fast-route: handle routing
* php-di/php-di: act as service container
* zendframework/zend-diactoros: a PHP package implements psr-7
* zendframework/zend-eventmanager: handle application event
* doctrine/annotations:for annotation usage
* zendframework/zend-stdlib: used to manage configs.

Penny ships Skeleton Application to get started, we can follow the installation steps, and we can see the welcome page.

The Penny’s Skeleton page brings Plates to manage template, so you don’t need to worry about adding manually. The template configureable in the skeleton’s config:

// config/di.php
return [
    'template' => \DI\object(\League\Plates\Engine::class)->constructor('./app/view/'),
    'router' => /* */
];

And about the routing, it brings the basic FastRoute‘s config:

// config/di.php
return [
    'template' => /* */
    'router' => function () {
        return \FastRoute\simpleDispatcher(function (\FastRoute\RouteCollector $r) {
            $r->addRoute('GET', '/', ['ClassicApp\Controller\IndexController', 'index']);
        });
    },
];

In ClassicApp\Controller\IndexController::index, we have Stream object that write with rendered template:

// app/Controller/IndexController.php
    public function index($request, $response)
    {
        $response->getBody()->write($this->template->render('index', [
            'title' => 'Home Page',
        ]));
        return $response;
    }

The template property in the controller above injected via @Inject annotation:

// app/Controller/IndexController.php
class IndexController {
    /**
     * @Inject("di")
     */
    private $di;

    /**
     * @Inject("template")
     */
    private $template;
}

And you’re already ready to go. But, what if You don’t like the way it worked, You need __construct injection? There we go:

// app/Controller/IndexController.php
use League\Plates\Engine as PlatesEngine;

class IndexController
{
    public function __construct(PlatesEngine $template)
    {
        $this->template = $template;
    }
}

And we can re-configure the config/di.php:

// config/di.php
use ClassicApp\Controller\IndexController;

return [

    IndexController::class => \DI\object(IndexController::class)->constructor(\DI\get('template')),

    'template' => /* */
    'router' => /* */
];

You want another container instead of php-di ? You can! The GianArb\Penny\App allows passing $container in 2nd parameter, so you can use it in public/index.php:

// public/index.php
$app = new \GianArb\Penny\App(null, $yourChoiceContainer);

Penny use Zend\EventManager to manage application event, There are 3 events that may be triggered:
* ERROR_DISPATCH: when error happen ( route not found, method not allowed, etc)
* filename.function: runnable
* filename.function_error: runnable but exception found.

Interesting? Take a look more on the site! Curious about the code behind it? Consult the code ;).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: