PSR7
interoperabilità HTTP
Massimiliano Arione
PUG Roma
24 aprile 2018
PSR?
PHP
Standard
Recommendations
FIG
https://www.php-fig.org/
Status # Title Status # Title
X 0 Autoloading Standard B 10 Security Reporting Process
A 1 Basic Coding Standard A 11 Container Interface
A 2 Coding Style Guide R 12 Extended Coding Style Guide
A 3 Logger Interface A 13 Hypermedia Links
A 4 Autoloading Standard B 14 Event Manager
B 5 PHPDoc Standard A 15 HTTP Handlers
A 6 Caching Interface A 16 Simple Cache
A 7 HTTP Message Interface D 17 HTTP Factories
B 8 Huggable Interface D 18 HTTP Client
B 9 Security Advisories
Status # Title Status # Title
X 0 Autoloading Standard B 10 Security Reporting Process
A 1 Basic Coding Standard A 11 Container Interface
A 2 Coding Style Guide R 12 Extended Coding Style Guide
A 3 Logger Interface A 13 Hypermedia Links
A 4 Autoloading Standard B 14 Event Manager
B 5 PHPDoc Standard A 15 HTTP Handlers
A 6 Caching Interface A 16 Simple Cache
A 7 HTTP Message Interface D 17 HTTP Factories
B 8 Huggable Interface D 18 HTTP Client
B 9 Security Advisories
Interfacce
<?php
namespace DoctrineCommonPersistence;
interface ObjectManager
{
public function find($className, $id);
public function persist($object);
public function remove($object);
/* … */
}
<?php
namespace DoctrineORM;
use DoctrineCommonPersistenceObjectManager;
interface EntityManagerInterface extends ObjectManager
{
public function getCache();
public function getConnection();
public function beginTransaction();
public function commit();
public function rollback();
/* ... */
}
<?php
namespace PUGRoma;
use DoctrineORMEntityManagerInterface;
class Pippo implements EntityManagerInterface, ArrayAccess
{
/* tutti i metodi delle interfacce implementate ... */
}
interfacce predefinite
● Traversable
● Iterator
● IteratorAggregate
● Throwable
● ArrayAccess
● Serializable
●
● Countable
● OuterIterator
● RecursiveIterator
● SeekableIterator
●
● DateTimeInterface
● JsonSerializable
S.O.L.I.D.
Single responsibility
Open/closed
Liskov substitution
Interface segregation
Dependency inversion
http://wall-skills.com/wp-content/uploads/2013/12/solid-OOP_wall-skills.pdf
Interfacce PSR
● PSR3 Logging
● PSR6 Caching
● PSR7 HTTP Message
● PSR11 Container
● PSR13 Hypermedia links
● PSR15 HTTP Handlers
● PSR16 SimpleCache
HTTP
HTTP
PSR7
PsrHttpMessageRequestInterface
PsrHttpMessageResponseInterface
PSR7 gerarchia
MessageInterface
RequestInterface ResponseInterface
ServerRequestInterface
PSR7 altre interfacce
● StreamInterface
● UploadedFileInterface
● UriInterface
<?php
namespace AppController;
use ApplicationCommandCreaElementoCommand;
use PsrHttpMessageServerRequestInterface;
use SimpleBusMessageBusMessageBus;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
use SymfonyBundleFrameworkBundleControllerAbstractController
final class PippoController extends AbstractController
{
public function creaElemento(MessageBus $bus, Request $request): Response
{
$command = CreaElementoCommand::fromRequest($request);
$bus->handle($command);
return $this->json([], Response::HTTP_CREATED);
}
}
<?php
namespace ApplicationCommand;
use SymfonyComponentHttpFoundationRequest;
class CreaElementoCommand
{
public $nome;
public $email;
public $telefono;
/* ... */
public static function fromRequest(Request $request): self
{
$params = $request->request->all();
$command = new static();
foreach ($params as $name => $value) {
if (property_exists(self::class, $name) {
$command->$name = $value;
}
}
return $command;
}
}
<?php
namespace ApplicationCommand;
use PsrHttpMessageServerRequestInterface;
class CreaElementoCommand
{
public $nome;
public $email;
public $telefono;
/* ... */
public static function fromRequest(ServerRequestInterface $request): self
{
$params = $request->getParsedBody();
$command = new static();
foreach ($params as $name => $value) {
if (property_exists(self::class, $name) {
$command->$name = $value;
}
}
return $command;
}
}
$ composer require 
symfony/psr-http-message-bridge 
sensio/framework-extra-bundle 
zendframework/zend-diactoros
<?php
namespace AppController;
use ApplicationCommandCreaElementoCommand;
use SimpleBusMessageBusMessageBus;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
use SymfonyBundleFrameworkBundleControllerAbstractController
final class PippoController extends AbstractController
{
public function creaElemento(MessageBus $bus, Request $request): Response
{
$command = CreaElementoCommand::fromRequest($request);
$bus->handle($command);
return $this->json([], Response::HTTP_CREATED);
}
}
<?php
namespace AppController;
use ApplicationCommandCreaElementoCommand;
use PsrHttpMessageServerRequestInterface;
use SimpleBusMessageBusMessageBus;
use SymfonyComponentHttpFoundationResponse;
use SymfonyBundleFrameworkBundleControllerAbstractController
final class PippoController extends AbstractController
{
public function creaElemento(MessageBus $bus, ServerRequestInterface $request): Response
{
$command = CreaElementoCommand::fromRequest($request);
$bus->handle($command);
return $this->json([], Response::HTTP_CREATED);
}
}
https://packagist.org/providers/psr/http-message-implementation
Happy coding!

PSR7 - interoperabilità HTTP