PHPackages                             iuravic/duktig-core - 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. [Framework](/categories/framework)
4. /
5. iuravic/duktig-core

ActiveLibrary[Framework](/categories/framework)

iuravic/duktig-core
===================

Core library for Duktig MVC micro web framework for PHP 7.1

063PHP

Since Jul 7Pushed 8y agoCompare

[ Source](https://github.com/iuravic/duktig-core)[ Packagist](https://packagist.org/packages/iuravic/duktig-core)[ RSS](/packages/iuravic-duktig-core/feed)WikiDiscussions master Synced 2d ago

READMEChangelogDependenciesVersions (1)Used By (0)

[![Build Status](https://camo.githubusercontent.com/9ef69c3841a3672334d62b6f178a62a015f4eb409a508e0d5a28515b9a136f4d/68747470733a2f2f7472617669732d63692e6f72672f697572617669632f64756b7469672d636f72652e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/iuravic/duktig-core) [![Coverage Status](https://camo.githubusercontent.com/7d14d6875e5444171e52abc5ee1b213fd03a58e8b30937b4eaf568c8dd9c8950/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f697572617669632f64756b7469672d636f72652f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/iuravic/duktig-core?branch=master)

duktig-core
===========

[](#duktig-core)

This is the core package for the Duktig micro MVC web framework.

A full skeleton web project using the Duktig framework is featured in the [`duktig-skeleton-web-app`](https://github.com/iuravic/duktig-skeleton-web-app) package, which uses this core package and implements all its dependencies.

Table of contents
=================

[](#table-of-contents)

- [About](#about)
    - [duktig-skeleton-web-app package](#duktig-skeleton-web-app-package)
    - [Purpose](#purpose)
    - [Standards](#standards)
    - [Features](#features)
- [Package design](#package-design)
- [Core services](#core-services)
- [Requirements](#requirements)
- [Dependency injection](#dependency-injection)
    - [Container](#container)
    - [Dependency resolution](#dependency-resolution)
    - [Lazy-loading](#lazy-loading)
- [Framework components](#framework-components)
    - [Routing](#routing)
    - [Controllers](#controllers)
    - [Middleware](#middleware)
    - [Templating](#templating)
    - [Events](#events)
    - [Error handling](#error-handling)
- [Configuration](#configuration)
- [Testing](#testing)

About
=====

[](#about)

Duktig is a light weight MVC micro web framework written for PHP 7.1. It was primarily created as an educational project, but it is also fully tested and feasible for production use. It implements the MVC pattern and features an IoC container, events system, and uses HTTP middleware.

`duktig-skeleton-web-app` package
---------------------------------

[](#duktig-skeleton-web-app-package)

The [`duktig-skeleton-web-app`](https://github.com/iuravic/duktig-skeleton-web-app) package is a full-featured project which is based on the `duktig-core` package. It can be used as a starting point for developing your own Duktig framework application since it readily implements all the necessary dependencies based on popular open-source projects and packages.

Purpose
-------

[](#purpose)

Duktig framework's goal is to deliver a flexible yet powerful framework for creating web applications by using the most feasible and up-to-date features and practices.

By learning from some of the most popular PHP web frameworks today ([Aura](http://auraphp.com/), [Silex](https://silex.sensiolabs.org/), [Slim](https://www.slimframework.com/), [Stack](http://stackphp.com/), [Yii2](https://github.com/yiisoft/yii2/), [Lumen](https://lumen.laravel.com/), [Symfony](https://symfony.com/), [Laravel](https://laravel.com/), [Bullet](http://bulletphp.com/), [Proton](https://github.com/alexbilbie/Proton)), Duktig's core architecture relies on modern principles and standards.

Standards
---------

[](#standards)

- [PSR](http://www.php-fig.org) compliant
    - PSR-2 coding, and PSR-4 autoloading standards
    - interfaces: PSR-3 logger, PSR-7 HTTP message, PSR-11 container, PSR-15 HTTP middlewares, PSR-17 HTTP factories
- decoupled package design
- powered by popular open source projects and libraries
- TDD developed, unit, integration, and functionally tested

Features
--------

[](#features)

- MVC pattern
- IoC and DI container
- HTTP middleware
- event system
- lazy loading

Package design
==============

[](#package-design)

Most of Duktig's core services are decoupled from the core package and packaged into their own modules. This kind of approach provides high flexibility and a good package design. Using interface injection, the object graph is naturally composed during the execution.

Core services
=============

[](#core-services)

The [`duktig-core`](https://github.com/iuravic/duktig-core) implements several of its own core services, while leaving out the implementation of most others to external projects:

- [configuration service](https://github.com/iuravic/duktig-core/blob/master/src/Core/Config/Config.php),
- [exception handler](https://github.com/iuravic/duktig-core/blob/master/src/Core/Exception/Handler/Handler.php),
- [response sender](https://github.com/iuravic/duktig-core/blob/master/src/Core/Http/ResponseSender.php),

These core services are registered in core's [`'Config/services.php'`](https://github.com/iuravic/duktig-core/blob/master/src/Config/services.php) file. If needed they can be overridden and replaced by your own configuration. This is achieved by using the `'skipCoreServices'` config parameter, in which case they must be specified by your own configuration.

`duktig-core` uses the [Auryn DI container](https://github.com/rdlowrey/auryn) out-of-the-box, or rather the adapter package [`duktig-auryn-adapter`](https://github.com/iuravic/duktig-auryn-adapter) which simply adapts its API to Duktig's [specification](https://github.com/iuravic/duktig-core/blob/master/src/Core/DI/ContainerInterface.php). The container can be changed to your own choice.

Requirements
============

[](#requirements)

The `duktig-core` package defines and uses a number of interfaces which need to be implemented by resolvable services at runtime. The [`duktig-skeleton-web-app`](https://github.com/iuravic/duktig-skeleton-web-app) demonstrates how this is done in a real case, and is a recommended starting point for writing your own Duktig framework application. Briefly put, to implement these requirements, an application (for example the `duktig-skeleton-web-app`) first includes all the required packages as [composer dependencies](https://github.com/iuravic/duktig-skeleton-web-app/blob/master/composer.json) and then [registers them as services](https://github.com/iuravic/duktig-skeleton-web-app/blob/master/src/Config/services.php).

Once implemented, the application has access to the implementations of the following interfaces:

- `Interop\Http\Factory\ServerRequestFactoryInterface` and `Interop\Http\Factory\ResponseFactoryInterface` - HTTP message factories
- `Interop\Http\ServerMiddleware\DelegateInterface` - HTTP middleware dispatcher service
- [`Duktig\Core\Event\Dispatcher\EventDispatcherInterface`](https://github.com/iuravic/duktig-core/blob/master/src/Core/Event/Dispatcher/EventDispatcherInterface.php) - event dispatcher
- [`Duktig\Core\View\RendererInterface`](https://github.com/iuravic/duktig-core/blob/master/src/Core/View/RendererInterface.php) - template renderer
- [`Duktig\Core\Route\Router\RouterInterface`](https://github.com/iuravic/duktig-core/blob/master/src/Core/Route/Router/RouterInterface.php) - router service
- `Psr\Log\LoggerInterface` - logger service

Dependency injection
====================

[](#dependency-injection)

Container
---------

[](#container)

The DI container must implement the [`Duktig\Core\DI\ContainerInterface`](https://github.com/iuravic/duktig-core/blob/master/src/Core/DI/ContainerInterface.php). This interface is an extension of the `Psr\Container\ContainerInterface` with a several methods of its own. The dependency resolution in Duktig is based on constructor arguments injection which is the central feature the container must implement.

By default, Duktig uses the [Auryn container](https://github.com/rdlowrey/auryn) out-of-the-box, or rather the [`duktig-auryn-adapter`](https://github.com/iuravic/duktig-auryn-adapter) package which adapts to the defined interface. This is defined in the `dutig-core` [configuration](https://github.com/iuravic/duktig-core/tree/master/src/Config). The container can however be changed to any PSR-11 container which additionally implements the `Duktig\Core\DI\ContainerInterface`.

### ContainerFactory

[](#containerfactory)

The container itself is instantiated and configured by the [`Duktig\Core\DI\ContainerFactory`](https://github.com/iuravic/duktig-core/blob/master/src/Core/DI/ContainerFactory.php). If the custom container class has any constructor parameters, the `ContainerFactory` will try to resolve and inject them by using the `ReflectionClass`.

The `ContainerFactory` then configures the container, by running it through the service configurators. The services are configured in your app's `services.php` config file.

Dependency resolution
---------------------

[](#dependency-resolution)

As with other standard PHP DI containers, the constructor parameter type hinting is used to provide dependency injection. The following entities in the framework are resolved by the container:

- services
- controllers
- closure-type route handlers
- middlewares
- event listeners

These entities will have their constructor parameters resolved and injected at runtime. Any dependency can be injected in this way, either if it was previously defined with the container as a service, or even if it is automatically provisioned, which of course depends on if the container of your choice supports the automatic provisioning feature (the Auryn DI container does).

Lazy-loading
------------

[](#lazy-loading)

The framework itself takes advantage of the lazy-loading optimization and delays the object creation in several cases, therefore improving performance. Ie. the controller resolution happens only when the end of the middleware stack is reached, and not sooner. Lazy-loading is naturally related to the container's `make()` method implementation. Therefore, if the container of your choice uses lazy-loading (which the Auryn DI container does), it will also be applied throughout the framework work flow.

Framework components
====================

[](#framework-components)

Routing
-------

[](#routing)

`duktig-core` defines its routing in terms of several entities. It uses a router which has the job to match the current request to the appropriate route. It also uses a route provider service which provides a simple API for fetching and identifying available routes.

### Router

[](#router)

Duktig's router is featured as a standalone service. The router must implement the [`Duktig\Core\Route\Router\RouterInterface`](https://github.com/iuravic/duktig-core/blob/master/src/Core/Route/Router/RouterInterface.php). This interface defines only one mandatory method `match` which matches the `Psr\Http\Message\ServerRequestInterface` object to a [`Duktig\Core\Route\Router\RouterMatch`](https://github.com/iuravic/duktig-core/blob/master/src/Core/Route/Router/RouterMatch.php) object. The `RouterMatch` is nothing more than a value object which represents the matched route; it holds the route which was matched and its parameters.

### Route

[](#route)

`Duktig\Core\Route\Route` is the Duktig's route model. Its form was heavily influenced by the [Symfony Route's](https://github.com/symfony/routing) route model, as it is one of the most feature-rich and popular route representations in the open-source community.

### RouteProvider

[](#routeprovider)

`Duktig\Core\Route\RouteProvider` is a service which provides access to the routes. It accesses the routes' configuration from the configuration services, and converts it to the `Route` objects, exposing them in a way of a several user-friendly API methods.

### Route handlers

[](#route-handlers)

A route can have two different kinds of resolvers:

- the first is a classical controller with an action method, where the controller extends the `BaseController` class exposing access to the request and some essential components,
- the second is a closure type handler, which is given directly in route configuration.

Both types of route handlers must return a `ResponseInterface` type object. For a closure type handler, it is recommended to use the `Interop\Http\Factory\ResponseFactoryInterface` to create a response instance, while a controller will already have the response prepared for use via the `BaseController` parent class.

Both types of handlers are dynamically resolved by the container, and have their constructor arguments dependencies injected upon creation.

Controllers
-----------

[](#controllers)

Controllers are assigned to routes and are in charge of generating a response. Alternatively, instead of defining special controller classes, a simpler [closure-type route handlers](https://github.com/iuravic/duktig-skeleton-web-app/blob/master/README.md#routes-1) can be used.

### `BaseController`

[](#basecontroller)

All controller classes should extend the base `Duktig\Core\Controller\BaseController` in order to get access to the application context, including the properties:

- `$request` - the PSR-7 request object
- `$response` - - a "fresh" PSR-7 response object
- `$queryParams` - parsed URI parameters
- `$renderer` - template rendering service
- `$config` - configuration service

`BaseController` also provides methods for quicker manipulation of the response object and its rendering.

### Route parameters

[](#route-parameters)

Route parameters are passed to the controller as the action method's parameters. Ie. if a route uses one string parameter `$param`, and assigns it to the `exampleAction` method, the parameter will be available to the action method in this way:

```
public function exampleAction(string $param) : ResponseInterface;
```

### Return type

[](#return-type)

Every controller or route handler must return a PSR-7 response object. The `$response` property is available for use within controller that extend the main `BaseController` class, which is internally generated by a PSR-17 `$responseFactory` service.

### Dependency injection

[](#dependency-injection-1)

Controllers will have their constructor parameters resolved and injected at runtime. Controllers, among other entities, are by default not given the access to the container, as this is widely considered as the service locator anti-pattern. However, no special restriction is imposed on this approach neither, and could easily be implemented. This practice is, however, strongly discouraged.

It may be quite needless to point this out specifically, but, naturally, when your controller defines it's own dependencies, it must also pay respect to its parent's dependencies as well, ie.:

```
