Download the PHP package woohoolabs/harmony without Composer

On this page you can find all versions of the php package woohoolabs/harmony. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package harmony

Woohoo Labs. Harmony

Latest Version on Packagist Build Status Coverage Status Quality Score Total Downloads Gitter

Woohoo Labs. Harmony is a PSR-15 compatible middleware dispatcher.

Harmony was born to be a totally flexible and almost invisible framework for your application. That's why Harmony supports the PSR-7, PSR-11, as well as the PSR-15 standards.

Table of Contents

Introduction

Rationale

This blog post explains the idea best why Harmony was started back in 2014: http://www.catonmat.net/blog/frameworks-dont-make-sense/

Features

Why Harmony?

There are a lot of very similar middleware dispatcher libraries out there, like Laminas-Stratigility, Slim Framework 3 or Relay. You might ask yourself, what is the purpose of yet another library with the same functionality?

We believe Harmony offers two key features which justify its existence:

Use cases

Certainly, Harmony won't suit the needs of all projects and teams: this framework works best for an experienced team with a longer term project. Less experienced teams - especially if they have short deadlines - should probably choose a framework with more features - working out-of-the box - in order to speed up development in its initial phase. Harmony's flexibility is the most advantageous when your software should be supported for a longer time.

Concepts

Woohoo Labs. Harmony is built upon two main concepts: middleware, which promote separation of concerns, and common interfaces, making it possible to rely on loosely coupled components.

By using middleware, you can easily take hands on the course of action of the request-response lifecycle: you can authenticate before routing, do some logging after the response has been sent, or you can even dispatch multiple routes in one request. This all can be achieved because everything in Harmony is a middleware, so the framework itself only consists of cc. 140 lines of code. This is why there is no framework-wide configuration, only middleware can be configured. What you do with Harmony depends only on your imagination and needs.

But middleware must work in cooperation (the router and the dispatcher are particularly tightly coupled to each other). That's why it is also important to provide common interfaces for the distinct components of the framework.

Naturally, we decided to use PSR-7 for modelling the HTTP request and response. In order to facilitate the usage of different DI Containers, we adapted PSR-11 (former Container-Interop) which is supported by various containers out of the box.

Middleware interface design

Woohoo Labs. Harmony's middleware interface design is based on the the PSR-15 de-facto standard.

If you want to learn about the specifics of this style, please refer to the following articles which describe the very concept:

Install

The only thing you need before getting started is Composer.

Install a PSR-7 implementation:

Because Harmony requires a PSR-7 implementation (a package which provides the psr/http-message-implementation virtual package), you must install one first. You may use Laminas Diactoros or any other library of your preference:

Install Harmony:

To install the latest version of this library, run the command below:

Note: The tests and examples won't be downloaded by default. You have to use composer require woohoolabs/harmony --prefer-source or clone the repository if you need them.

Harmony 6.2+ requires PHP 7.4 at least, but you may use Harmony 6.1 for PHP 7.1+.

Install the optional dependencies:

If you want to use the default middleware stack then you have to require the following dependencies too:

Basic Usage

Define your endpoints:

The following example applies only if you use the default dispatcher middleware. There are two important things to note here: first, each dispatchable endpoint receives a Psr\Http\Message\ServerRequestInterface and a Psr\Http\Message\ResponseInterface object as parameter and the latter is expected to be manipulated and returned. Secondly, you can not only use class methods as endpoints, it is possible to define other callables too (see below in the routing section).

Define your routes:

The following example applies only if you use the default router middleware which is based on FastRoute, the library of Nikita Popov. We chose to use it by default because of its performance and simplicity. You can read more about it in Nikita's blog.

Let's add the routes for the aforementioned endpoints to FastRoute:

Finally, launch the app:

You have to register all the prior middleware in order for the framework to function properly:

Note that there is a second optional argument of Harmony::addMiddleware() with which you can define the ID of a middleware (doing so is necessary if you want to call Harmony::getMiddleware() somewhere in your code).

Of course, it is completely up to you how you add additional middleware or how you replace them with your own implementations. When you'd like to go live, call $harmony->run()!

Advanced Usage

Using invokable class controllers

Most of the time, you will define your endpoints (~controller actions) as regular callables as shown in the section about the default router:

Nowadays, there is an increasing popularity of controllers containing only one action. In this case it is a general practice to implement the __invoke() magic method. When following this school of thought, your route definition can be simplified as seen below:

Note: In case you use a different router or dispatcher than the default ones, please make sure if the feature is available for you.

If you are interested in how you could benefit from invokable controllers in the context of the Action-Domain-Responder pattern, you can find an insightful description in Paul M. Jones' blog post.

Using your favourite DI Container with Harmony

The motivation of creating Woohoo Labs. Harmony was to become able to change every single aspect of the framework. That's why you can use any DI Container you want.

For this purpose, we chose to build upon PSR-11 - the most widespread common interface for DI Containers - in the built-in DispatcherMiddleware.

It's also important to know that the DispatcherMiddleware uses the BasicContainer by default. It's nothing more than a very silly DIC which tries to create objects based on their class name (so calling $basicContainer->get(Foo::class) would create a new Foo instance).

But if you provide an argument to the middleware's constructor, you can use your favourite PSR-11 compliant DI Container too. Let's have a look at an example where one would like to swap BasicContainer with Zen:

Creating custom middleware

New middleware also has to implement the PSR-15 MiddlewareInterface. Let's see an example:

And when you are ready, attach it to Harmony:

What to do if you do not want to invoke the remaining middleware (possibly because of an error)? Then you can simply manipulate and return a response whose "prototype" was passed to the middleware in its constructor. You can see this in action in the following example:

Then

Defining conditions

Non-trivial applications often need some kind of branching during the execution of their middleware pipeline. A possible use-case is when they want to perform authentication only for some of their endpoints or when they want to check for a CSRF token if the request method is POST. With Harmony 2 branching was also easy to handle, but Harmony 3+ helps you to optimize the performance of conditional logic in your middleware.

Let's revisit our authentication middleware example from the last section! This time, we only want to authenticate endpoints below the /users path. In Harmony 2, we had to achieve it with something like this:

And finally attach the middleware to Harmony:

You had to check the current URI inside the middleware and the problem was solved. The downside of doing this is that AuthenticationMiddleware and all its dependencies are instantiated for each request even though authentication is not needed at all! This can be a major inconvenience if you depend on a big object graph.

In Harmony 3+, however, you are able to use conditions in order to optimize the number of invoked middleware. In this case you can utilize the built-in PathPrefixCondition. You only have to attach it to Harmony:

This way, AuthenticationMiddleware will only be instantiated when PathPrefixCondition evaluates to true (when the current URI path starts with /users). Furthermore, you are able to attach more middleware to Harmony in the anonymous function. They will be executed together, as if they were part of a containing middleware.

Here is the complete list of the built-in conditions:

Examples

If you want to see a really basic application structure in action, have a look at the examples. If docker-compose and make is available on your system, then run the following commands in order to try out the example app:

If you don't have make, you can copy the underlying commands, and directly use them in your terminal.

Finally, the example app is available at localhost:8080.

If you modified the .env file, you should change the port to the value of the HOST_WEB_PORT variable.

Example URIs:

When you finished your work, simply stop the webserver:

If the prerequisites are not available for you, you have to set up a webserver on your host, install PHP, as well as the dependencies via Composer.

Versioning

This library follows SemVer v2.0.0.

Change Log

Please see CHANGELOG for more information on what has changed recently.

Testing

Harmony has a PHPUnit test suite. To run the tests, run the following command from the project folder:

Additionally, you may run docker-compose up or make test to execute the tests.

Contributing

Please see CONTRIBUTING for details.

Support

Please see SUPPORT for details.

Credits

License

The MIT License (MIT). Please see the License File for more information.


All versions of harmony with dependencies

PHP Build Version
Package Version
Requires php Version ^8.0.0
psr/container Version ^1.1.0||^2.0.0
psr/http-message-implementation Version ^1.0.0
psr/http-server-handler Version ^1.0.0
psr/http-server-middleware Version ^1.0.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package woohoolabs/harmony contains the following files

Loading the files please wait ....