PSR Adapters

Introduction

A group called The PHP Framework Interop Group (FIG) came together to try and solve some of the issues with reusing components between frameworks. For example, most frameworks tend to write their own HTTP requests, responses, DI containers, etc. Having many different implementations to solve the same thing makes it difficult to build libraries that could work across frameworks. So, the FIG set about introducing some standards called PSRs to simplify reusing these components across frameworks.

For reasons we'll discuss in the next section, Aphiria does not use most PSRs natively. However, we do offer adapters for PSR-7 and PSR-11 to make it possible to convert Aphiria models to PSR-compliant models and vice versa.

Why Doesn't Aphiria Adopt All The PSRs?

A lot of major frameworks, eg Symfony and Laravel, have also decided not to adopt some PSRs. For example, PSR-7 has been pretty widely criticized for the following reasons:

These negatives aside, PSR-7 did do a decent job in some of its modeling of HTTP messages. In fact, some of Aphiria's message models are somewhat similar to PSR-7, but attempt to improve their shortcomings.

PSR-11 was too limiting, eg no targeted bindings, and didn't provide enough value to justify supporting it.

PSR-7

PSR-7 is focused on creating a standard for HTTP messages, URIs, streams, and uploaded files. For those that wish to use third party libraries that only support PSR-7, we've created an easy way to convert to and from PSR-7 via Psr7Factory.

use Aphiria\PsrAdapters\Psr7\Psr7Factory;
use Nyholm\Psr7\Factory\Psr17Factory;

// This third party factory can create all PSR-7 models for us
$psr17Factory = new Psr17Factory();
$psr7Factory = new Psr7Factory(
    psr7RequestFactory: $psr17Factory,
    psr7ResponseFactory: $psr17Factory,
    psr7StreamFactory: $psr17Factory,
    psr7UploadedFileFactory: $psr17Factory,
    psr7UriFactory: $psr17Factory
);

We'll use this factory in the examples below.

Requests

Create a PSR-7 request from an Aphiria request:

$psr7Request = $psr7Factory->createPsr7Request($aphiriaRequest);

Create an Aphiria request from a PSR-7 request:

$aphiriaRequest = $psr7Factory->createAphiriaRequest($psr7Request);

Responses

Create a PSR-7 response from an Aphiria response:

$psr7Response = $psr7Factory->createPsr7Response($aphiriaResponse);

Create an Aphiria response from a PSR-7 response:

$aphiriaResponse = $psr7Factory->createAphiriaResponse($psr7Response);

Streams

Create a PSR-7 stream from an Aphiria stream:

$psr7Stream = $psr7Factory->createPsr7Stream($aphiriaStream);

Create an Aphiria stream from a PSR-7 stream:

$aphiriaStream = $psr7Factory->createAphiriaStream($psr7Stream);

URIs

Create a PSR-7 URI from an Aphiria URI:

$psr7Uri = $psr7Factory->createPsr7Uri($aphiriaUri);

Create an Aphiria URI from a PSR-7 URI:

$aphiriaUri = $psr7Factory->createAphiriaUri($psr7Uri);

Uploaded Files

Create PSR-7 uploaded files from an Aphiria request:

$psr7UploadedFiles = $psr7Factory->createPsr7UploadedFiles($aphiriaRequest);

PSR-11

PSR-11's aim was to give a simple interface for dependency injection containers to implement. Although IContainer does not natively support PSR-11, it's trivial to create a container that does.

Creating a PSR-11 Container

use Aphiria\DependencyInjection\Container;
use Aphiria\PsrAdapters\Psr11\Psr11Container;

$aphiriaContainer = new Container();
$psr11Container = new Psr11Container($aphiriaContainer);

if ($psr11Container->has(Foo::class)) {
    $foo = $psr11Container->get(Foo::class);
}