Skip to main content

Conduit: Middleware for PHP

·618 words·3 mins
Hari KT
Author
Hari KT
Freelancer | Founder of Tripti and Tanvish | Maintainer of Aura for PHP, created by Paul M Jones

Long back, I happened to talk with Beau Simensen about stackphp on #auraphp channel. It was hard for me to digest when I noticed it need symfony/http-kernel and its dependencies.

After a few months, I started to like the middleware approach of slim framework and wanted to push it to aura. But nothing happened there.

Conduit to rescue
#

Conduit is a Middleware for PHP built by Matthew Weier O’Phinney lead of Zend framework. Conduit supports the current PSR-7 proposal. I believe like the many PSR’s, PSR-7 will be a revolution in the PHP world. Conduit is really a micro framework and can grow with your project.

Starting your project
#

I hope you know about the tool composer and know about PHP 5.3 to follow the tutorial.

1
2
3
4
mkdir sample-project
cd sample-project
composer require "phly/conduit:0.10.*"
mkdir web

We have created an extra web folder, so it acts as the document root. Create an index.php file in the web folder and lets start serving our first Hello conduit! message.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php
require dirname(__DIR__) . '/vendor/autoload.php';

use Phly\Conduit\Middleware;
use Phly\Http\Server;

$app = new Middleware();
$app->pipe('/', function ($request, $response, $next) {
    return $response->write('Hello conduit!')->end();
});
$server = Server::createServer($app,
  $_SERVER,
  $_GET,
  $_POST,
  $_COOKIE,
  $_FILES
);
$server->listen();

Start your web server, or fire your built in PHP server.

1
php -S localhost:8000 web/index.php -t web

Point your browser to http://localhost:8000 and you can see Hello conduit!.

Middlewares
#

Conduit route is very limited and will not handle dynamic routing. So we need a router middleware to resuce. Let us build our first router middleware. If you check the docs middleware can be a closure, invokable objects, array callback etc. We will stick with closure in the examples.

The idea is same even if you are using a different library.

  1. Get the path via $request->getUri()->getPath()
  2. Check router if the path is matching
  3. If
    • no call the next middleware in stack. ie return $next()
    • yes execute the controller and return back the response

Be sure that if you change something you need to return the response. Because Request and Response are immutable.

In-order to build something like the above, we need a router library which can handle routing, and a dispatcher library which can handle the necessary operation when a route is found.

Install the dependencies.

1
composer require "aura/router:~2.0" "aura/dispatcher:~2.0"

The router middleware will look like as below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$router = new \Aura\Router\Router(
    new \Aura\Router\RouteCollection(new \Aura\Router\RouteFactory),
    new \Aura\Router\Generator
);
$dispatcher = new \Aura\Dispatcher\Dispatcher(array(), 'controller', 'action');

$app->pipe(function ($request, $response, $next) use ($router, $dispatcher) {
    $path = $request->getUri()->getPath();
    $route = $router->match($path, $request->getServerParams());
    if (! $route) {
        return $next();
    }
    $params = $route->params;
    $params['request'] = $request;
    $params['response'] = $response;
    $result = $dispatcher->__invoke($params);
    if ($result instanceof \Psr\Http\Message\ResponseInterface) {
        $response = $result;
    } else {
        $response = $response->write($result)->end();
    }
    return $response;
});

Now your router middleware can handle dynamic things. You can see the full example over gist.

You may need an authentication middleware to check whether the user is authenticated, or a content negotiation middleware to set the corresponding Content-Type header in the response.

I have created a skelton project which have a router middleware, authentication middleware and negotiation middleware with the help of a few libraries. Less libraray means less code to maintain, easy to understand and debug the code behind the scenes.

Today, I noticed one question over reddit Moving to a real framework.. need help with the migration wrote my suggestion how conduit + aura can help.

Play and enjoy!

Related

Experimenting With Different PHP Frameworks

·765 words·4 mins
Whenever I get some time, I try to learn and experiment on different frameworks. I would like to stay away from pin pointing to the frameworks I have looked, so they don’t feel bad. Long live components # Components are awesome!. You can plug your favourite components to any system. Thank you composer. One strong preference choosing a framework was

Improving Environment Values in Aura v2

·208 words·1 min
Aura v2 framework probably have missed a better way to handle environment variables. But that doesn’t make you stall. Things can be improved ;-). Assume you are already using aura framework and is at root of the project. We are going to make use of vlucas/phpdotenv , alternatives are there if you are interested to experiment. 1 composer require vlucas/phpdotenv Edit the file config/_env.php and add Dotenv::load(/path/to/.env); to the first line. If you have not modified anything it will look as below

Speed Up Configuration in Aura v2

·322 words·2 mins
Aura v2 added auto resolution in-order to help lazy people writing configuration manually. Even though it was introduced to help, it introduced a few issues. So auto resolution will be disabled in the future. Some of the complains/suggestions are how to easily write the di configuration. So introducing you FOA.DiConfig Installation # 1 composer require foa/di-config Usage # 1 2 3 vendor/bin/di-config-dump Usage : vendor/bin/di-config-dump /real/path/to/file.php Usage : vendor/bin/di-config-dump /real/path/to/directory Example 1 # Let’s assume you have