Developing middleware
web APIs in PHP 7

by Enrico Zimuel - @ezimuel
Senior Software Engineer
Zend, a Rogue Wave Company (USA)


CloudConf, Turin, 16th March 2017

About me

PHP

  • PHP: Hypertext Preprocessor
  • The most popular server-side language: PHP is used by 82.6% of all the websites (source: w3techs.com)
  • Used by Facebook, Wikipedia, Yahoo, Etsy, Flickr, Digg, etc
  • 21 years of usage, since 1995
  • Full OOP support since PHP 5

PHP 7

Released: 3 December 2015

Last major was PHP 5, 13 July 2004

Last release is 7.1.2 (16 Feb 2017)

PHP 7 performance

PHP 7 is also faster than Python 3!

Benchmark


$a = [];
for ($i = 0; $i < 1000000; $i++) {
  $a[$i] = ["hello"];
}
echo memory_get_usage(true);
PHP 5.6 PHP 7
Memory Usage 428 MB 33 MB
Execution time 0.49 sec 0.06 sec

Moving to PHP 7

  • Badoo saved one million dollars switching to PHP 7 (source)
  • Tumblr reduced the latency and CPU load by half moving to PHP 7 (source)
  • Dailymotion handles twice more traffic with same infrastructure switching to PHP 7 (source)

PHP 7 is not only fast!

  • Return and Scalar Type Declarations
  • Improved Exception hierarchy
  • Many fatal errors converted to Exceptions
  • Secure random number generator
  • Authenticated encryption AEAD (PHP 7.1+)
  • Nullable types (PHP 7.1+)
  • and more!

Web APIs

API stands for Application Programming Interface and as a term, specifies how software should interact.

Web APIs are delivered over HTTP.

HTTP IN/OUT

Example

Request:


GET /api/version

Response:


HTTP/1.1 200 OK
Connection: close
Content-Length: 17
Content-Type: application/json

{
  "version": "1.0"
}
	

How to develop
a web API in PHP?

Middleware

Middleware

A function that gets a request and generates a response


use Psr\Http\Message\ServerRequestInterface as Request;
use Interop\Http\ServerMiddleware\DelegateInterface;

function (Request $request, DelegateInterface $next)
{
    // doing something with $request...
    // for instance calling the delegate middleware $next
    $response = $next->process($request);
    // manipulate the $response
    return $response;
}
This is called lambda middleware.

DelegateInterface


namespace Interop\Http\ServerMiddleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

interface DelegateInterface
{
    /**
     * @return ResponseInterface;
     */
    public function process(ServerRequestInterface $request);
}
DelegateInterface is part of PSR-15 HTTP Middleware proposal

Expressive 2.0

The PHP framework for Middleware applications

  • PSR-7 support (using zend-diactoros)
  • Support of lambda middleware (PSR-15) and double pass ($request, $response, $next)
  • Piping workflow (using zend-stratigility)
  • Features: routing, container-interop (PSR-11), templating, error handling
  • Last release 2.0.2, 13th March 2017

Installation

You can install Expressive 2.0 using composer:

composer require zendframework/zend-expressive
                 zendframework/zend-expressive-fastroute
                 zendframework/zend-servicemanager

Create a public folder:

mkdir public

Bootstrap script

public/index.php


use Interop\Http\ServerMiddleware\DelegateInterface;
use Zend\Diactoros\Response\JsonResponse;
use Zend\Expressive\AppFactory;

chdir(dirname(__DIR__));
require 'vendor/autoload.php';

$app = AppFactory::create();
$app->get('/api/ping', function ($request, DelegateInterface $delegate) {
    return new JsonResponse(['ack' => time()]);
});

$app->pipeRoutingMiddleware();
$app->pipeDispatchMiddleware();
$app->run();

Running the API

Start a web server using the public folder.

For instance, using the PHP's built-in web server:


php -S 0.0.0.0:8080 -t public/

Call the API at http://localhost:8080/api/ping

DEMO

Deploy a simple API in the cloud
using Amazon Web Service and Zend Server 9

Thanks!

Contact me: enrico.zimuel [at] roguewave.com

Blog and web site: www.zimuel.it

Follow me: @ezimuel



Creative Commons License
This work is licensed under a
Creative Commons Attribution-ShareAlike 3.0 Unported License.
I used reveal.js to make this presentation.