hermes-php/hermes-micro

This package is abandoned and no longer maintained. The author suggests using the espresso/skeleton package instead.

The framework for devs who know what they're doing

Installs: 17

Dependents: 0

Suggesters: 0

Type:project

2.0.0 2019-03-16 02:58 UTC

README

Power has come

Introduction

Thanks for trusting in Hermes. We believe this minimal, next-generation, PHP Framework will prove to be a valuable tool for you.

Before starting, you must know that we have made some important decisions for you that, if they don't suit you, you can totally change. For instance:

  • We have chosen an PSR-7 (Http Messages) implementation for you, called Zend Diactoros. It also comes with a PSR-17 (Http Message Factories) implementation.
  • We have chosen a PSR-11 (DI Container) implementation for you, League Container. Feel free to swap it for the container you like the most.
  • We have chosen a Zend Router implementation, Nikita's famous Fast Route. You can change it also if it does not suit your needs.
  • We have added Road Runner, which is a high-performance PHP application server, load-balancer and process manager. Read the quick start guide to know more.
  • We have added http-interop/response-sender which is a simple function to emit PSR-7 responses to a client.
  • We have wired up everything using simple PHP config files using the container. Feel free to create your own configuration methods. All of that lives in the config/ folder.
  • We have added a views folder, with the view of the Hermes homepage mainly for making it look nice. You SHOULD delete the views folder and the default homepage handler (in App\Http\Middleware).
  • We have created a public/ with an entry-point script index.php just in case you want to go back to the old ways of PHP and put it behind an Apache or Nginx.

Keep all this in mind and do the changes you need early in the development process.

Quick Start Guide

This little guide will help you with the basic stuff. It is very superficial and assumes a lot of knowledge. If you find yourself in trouble following it, just read the proper Hermes Docs.

On Serving your app over HTTP

Hermes Micro supports three ways of serving your app over Http.

Traditional Index Front Controller

One is the traditional public folder with the index.php front controller. You can point to that script with any web server (Apache, Nginx + PHP-FPM) and execute it. This entry-point is really useful for development with PHP's built-in dev web server. Just run php -S 0.0.0.0:8000 -t public and everything will be running.

React PHP Web Server

The other way, a little bit more "modern" is to use React's PHP HTTP Web Server to create a HTTP Server over a TCP Socket (yeah, all of that in PHP) and execute your app as a long running process. You can do this running php bin/server.php. This is very performant, as the files are parsed only once by the Zend Engine, auto-loaded only once by Composer's Autoload, and configured only once by your DI Container. However, you must write code that will be aware of possible memory leaks between requests. If you want to see code changes, you have to restart the server.

This is the ideal setup if you are going to make an stateless docker container out of your application, and it's the command ran by default by the Dockerfile.

Important Note: When using React PHP web server, your static files (assets) may not load correctly if you don't use a middleware. Check hermes-php/asset-middleware to get one. If you don't need your app to serve static files, you can just ignore this.

Road Runner Load Balancer

When you want to serve your app on a single machine but putting a process manager and load balancer behind it so you can get the most out of your cores, you can use Road Runner. It is a small Go app that is able to spawn several processes of your application and handle the load among them. We include a default config file for it and a worker, but you have to download the binary for your platform yourself. This is by far the most performant way of serving your app in a single machine (way way faster than PHP-FPM+Nginx+OpCache).

Benchmarking

We benchmarked the homepage of Hermes Micro using ab on the three ways of serving your application.

Test: 5000 requests (50 concurrent)

ServerTotal TimeCompletedFailedReq/SecTime per Req
Road Runner2.377 secs500002103.4623.770 ms
ReactPHP7.794 secs50000641.4977.943 ms
PHP Dev Server16.861 secs50000296.54168.609 ms

Facts:

  • React PHP at least two times faster as regular PHP Dev Server.
  • Road Runner is at least three times faster than React PHP.
  • When raised the number of concurrent requests to 150, both React PHP and PHP Dev Server crashed and complained of too many requests. Road Runner handled it with no problem.

Road Runner is by far the most superior because it spawns four workers and distributes the load among them, using all cores very efficiently. React PHP cannot compete with that as it uses just one core, but is still faster than the PHP Dev Server due to the bootstraping that's already in place in each Request.

  • Tests were performed in a Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz (4 cores) with 16 GB RAM.

On Developing your app

As you may have realised, Hermes does not use fancy yaml, toml or json config files to wire up your services and bootstrap your code: you have to do everything yourself. It allows you to have full flexibility at the cost of development speed.

We believe that Programming is not magic with all our heart, that's why Hermes will not help you with creating cruds or auto-generating code for you. You have other HTTP Frameworks for that. Programming is hard work: don't try to use tools to avoid writing code. Follow that advice, and you'll see how much you'll grow as a professional.

That being said, I don't mean to say that you have to write every single component of your application yourself. Rely on libraries when you can, specially those that are interoperable. You can build a pretty solid HTTP layer using PSR-15 Middleware.

For libraries that are not that interoperable, implement a contract suitable for your app and create adapters. Don't lock yourself in a vendor for not following best practices.

Register services in the container and wire up everything from there. This will help you simplify your bootstraping. Don't forget to write code comments as they are now for some components, so people can find service definitions easily.