PHPackages                             psg/sr2 - 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. [HTTP &amp; Networking](/categories/http)
4. /
5. psg/sr2

ActiveLibrary[HTTP &amp; Networking](/categories/http)

psg/sr2
=======

App Standardization

0.1(4y ago)091MITPHPPHP &gt;=5.3.0

Since Jul 14Pushed 4y ago1 watchersCompare

[ Source](https://github.com/PHP-SG/sr-2)[ Packagist](https://packagist.org/packages/psg/sr2)[ Docs](https://github.com/php-sg/sr-2)[ RSS](/packages/psg-sr2/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependencies (1)Versions (2)Used By (1)

PSG SR 2 App Standardization
============================

[](#psg-sr-2-app-standardization)

```
composer require psg/sr2
```

```
class App implements Psg\Sr2\LayeredApp{}
```

Concepts
--------

[](#concepts)

**Types**

- Beforeware : outerware for setting of configuration
- Frontware : middleware caring only about the front
- Middleware : regular middleware the wraps the core and other middleware
- Coreware : the core app logic that is wrapped by middleware
- Backware : middleware caring only about the back
- Afterware : outerware for doing things after the resopnse, like cleaning up

[![Layered App](about/LayeredApp.png?raw=true "Layered App")](about/LayeredApp.png?raw=true)

**ExitResponseInterface**For Frontware to force a bypass, because it does not control the flow by calling next, it must return a special response implementing ExitResponseInterface. It does this through the app factory `$app->createExitResponse`, which is just like `createResponse`.

### Request And Response Flow

[](#request-and-response-flow)

The above diagram is an oversimplification. The reality looks more like this: [![Layered App](about/LA_request_response_flow_variance.png?raw=true "Layered App")](about/LA_request_response_flow_variance.png?raw=true)

Here you can see that the response is forwarded to the core from the frontware.

### Coreware

[](#coreware)

In Apps, there is an idea of a core which is usually called the controller. What is special about this core is that, regardless of what middleware is added during the running of the app, the core will always be executed at the core (whereas, where middleware is executed depends on the list of other middleware). I decided to call this `core` instead of `control` to make it more generic (it also includes running view code). I also decided to make this a single callable or {instantiable thing with an \_\_invoke method}. In my implementation, I provide the callable with the parameters ($request, $response, $app). It is, however, expectable that frameworks will want to:

- inject parameters as necessary into the core call
- inject parameters into the \_\_construct if the core is an instantiable As such, the parameters are left up to the framework.

Middleware, like a router, can set the core using `$app->core($core)`. The `$app->core()` method sets this coreware, and will overwrite anything that exists priorhand as the core. I decided that the coreware should not be multiple. Coreware is not expected to be generic, it is expected to be specific to the app, so a list is unnecessary.

There is the semblance of a conceptual issue about the `has` function. Since outerware is now present, and there is front and back specific middleware, what does `has` refer to?

Extension
---------

[](#extension)

Depending on demand and my free time, I will add events and container extensions, probably using the FIG PSRs.

Example
-------

[](#example)

See [SR2-implementation](https://github.com/PHP-SG/sr-2-implementation)

###  Health Score

18

—

LowBetter than 8% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity4

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1769d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/4543facab3c88d548b98d8472b532faf7bcd00555cc47c0dc808d935f8d3d73f?d=identicon)[grithin](/maintainers/grithin)

---

Top Contributors

[![grithin](https://avatars.githubusercontent.com/u/7241358?v=4)](https://github.com/grithin "grithin (2 commits)")

---

Tags

httpresponserequesthttp-messagefactorysr2

### Embed Badge

![Health badge](/badges/psg-sr2/health.svg)

```
[![Health](https://phpackages.com/badges/psg-sr2/health.svg)](https://phpackages.com/packages/psg-sr2)
```

###  Alternatives

[psr/http-message

Common interface for HTTP messages

7.1k1.0B5.5k](/packages/psr-http-message)[psr/http-factory

PSR-17: Common interfaces for PSR-7 HTTP message factories

1.9k692.9M1.9k](/packages/psr-http-factory)[fig/http-message-util

Utility classes and constants for use with PSR-7 (psr/http-message)

39489.0M274](/packages/fig-http-message-util)[chillerlan/php-httpinterface

A PSR-7/17/18 http message/client implementation

1417.1k5](/packages/chillerlan-php-httpinterface)[art4/requests-psr18-adapter

Use WordPress/Requests as a PSR-18 HTTP client

153.3k](/packages/art4-requests-psr18-adapter)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
