PHPackages                             mudge/engine - 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. mudge/engine

ActiveLibrary[Framework](/categories/framework)

mudge/engine
============

A tiny little PHP web framework written over a Bank Holiday weekend.

019PHP

Since Jan 1Pushed 8y agoCompare

[ Source](https://github.com/mudge/engine)[ Packagist](https://packagist.org/packages/mudge/engine)[ RSS](/packages/mudge-engine/feed)WikiDiscussions master Synced 2w ago

READMEChangelogDependenciesVersions (1)Used By (0)

Engine [![Build Status](https://camo.githubusercontent.com/63a002c7aef42dc7c5f048378d80874fc86232926901661e43d68adfc8cc73b0/68747470733a2f2f7472617669732d63692e6f72672f6d756467652f656e67696e652e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/mudge/engine)
==========================================================================================================================================================================================================================================================================

[](#engine-)

A tiny little PHP web framework written over a Bank Holiday weekend.

**Current version:** Unreleased
**Supported PHP versions:** 7.1, 7.2

Installation
------------

[](#installation)

```
$ composer create-project mudge/engine-skeleton:dev-master my-project
$ cd my-project
$ php -S localhost:8080 -t public
```

Design
------

[](#design)

It is tempting to think of the HTTP request response cycle as a pure function `f` that accepts some request (perhaps as a raw HTTP string or as some wrapper object) and produces a single response (again, perhaps as a raw string or a wrapper object):

```
+-------------------+     +---+     +----------------------------------------+
| GET / HTTP/2      | --> | f | --> | HTTP/2 200                             |
| Host: example.com |     +---+     | Content-Type: text/html; charset=utf-8 |
+-------------------+               |                                        |
       Request                      | ...                     |
                                    +----------------------------------------+
                                                     Response

```

However, this mental model isn't quite right as it's not true that all requests produce a single response all in one go. For example, it is possible for a response to be sent in chunks: perhaps a request immediately receives some headers in response before the body is returned in parts. It's also possible for a response to never end by continuously streaming (e.g. think of the Twitter streaming APIs).

Therefore, Engine takes an alternative approach: modelling the typical request response cycle as a function that takes *both* a request and a response object, the latter of which is a sort of open file handle allowing the user to send headers, etc. at any point during processing. This means that responses are created purely through side-effects which is a messier way of thinking about it but maps more closely to reality.

```
+-------------------+     +---+
| GET / HTTP/2      | --> |   |
| Host: example.com |     |   |
+-------------------+     |   |
       Request            | f |
                          |   |
+-------------------+     |   |
|                   | --> |   |
+-------------------+     +---+
       Response

```

Engine uses the [Model-view-controller](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) pattern but controllers are objects that are initialized with a `Request`, `Response` and a logger.

The `Request` is a value object offering access to the request URI, method, any `GET` or `POST` parameters and any cookies or session data.

The `Response` object allows you to send data in response to the request via various methods:

- `redirect(string $location): void`: send a redirect header;
- `header(string $header): void`: send any arbitrary header;
- `render(string $template, array $variables = []): void`: render a [Twig](https://twig.symfony.com/) template with the given variables;
- `notFound(): void`: return a `404 Not Found` response with a template called `404.html`;
- `forbidden(): void`: return a `403 Forbidden` response with a template called `403.html`;
- `methodNotAllowed(): void`: return a `405 Method Not Allowed` response with a template called `405.html`.

Note that all methods return `void` as they work purely through side-effects: namely, sending data to the client.

Controller actions are therefore typical methods on the controller instance with access to the `request`, `response` and `logger` (see [Usage](#usage) for an example). As these are plain PHP objects, all the usual techniques such as composition and inheritance are available for sharing behaviour between controllers.

As for how controllers are instantiated and actions called: the `Router` is responsible for this and contains a map of HTTP methods and paths to controller classes and actions, e.g.

```
+-------------+     +----------------------+
| GET /       | --> | HomeController#index |
+-------------+     +----------------------+

+-------------+     +---------------------------+
| POST /login | --> | SessionsController#create |
+-------------+     +---------------------------+

```

The [Engine Skeleton](https://github.com/mudge/engine-skeleton) project will create a `public/index.php` which sets up a new `Router`, populates it with a default route, creates a `Request` and empty `Response` and routes it accordingly.

```
            +-------------------+     +-----------------------------+     +------------------+
            | GET / HTTP/2      | --> | GET / -> HomepageController | --> |                  |
 __O__  --> | Host: example.com |     |          index              |     |      index       |
   |        +-------------------+     +-----------------------------+     |                  |
   |              Request                        Router                   |                  |
   |                                                                      |                  |
   |                                                       +--------+     |                  |
   |     |                  |
  / \                                                      |        |
