Bonjour,

j'ai suivis le tuto sur les middleware dans la serie mise en pratique de la POO en PHP et je bloque sur la mise en place de whoops

Ce que je fais

<?php

namespace Framework;

use Exception;
use DI\ContainerBuilder;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

class App implements RequestHandlerInterface
{

    /**
     * @var [ContainerInterface]
     */
    private $container;

    private $modules = [];

    private $definition;

    private $middlewares;

    private $index = 0;

    public function __construct(string $definition)
    {
        $this->definition = $definition;
    }

    /**
     * Ajoute un module à l'application
     *
     * @param [type] $module
     * @return self
     */
    public function addModule(string $module): self
    {
        $this->modules[] = $module;
        return $this;
    }

    public function run(ServerRequestInterface $request): ResponseInterface
    {
        foreach ($this->modules as $module) {
            $this->getContainer()->get($module);
        }
        return $this->handle($request);
    }

    /**
     * Ajoute un middleware
     *
     * @param string $middleware
     * @return self
     */
    public function pipe($middleware): self
    {
        $this->middlewares[] = $middleware;
        return $this;
    }

    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        $middleware = $this->getMiddleware();
        if(is_null($middleware)) {
            throw new Exception('Aucun middleware intercepté');
        } elseif(is_callable($middleware)) {
            return call_user_func_array($middleware, [$request, [$this, 'handle']]);
        } elseif ($middleware instanceof MiddlewareInterface) {
            return $middleware->process($request, $this);
        }
    }

    private function getMiddleware()
    {
        if (array_key_exists($this->index, $this->middlewares)) {
            $middleware = $this->getContainer()->get($this->middlewares[$this->index]);
            $this->index++;
            return $middleware;
        }
        return null;
    }

    /**
     * @return ContainerInterface
     */
    private function getContainer(): ContainerInterface
    {
        if($this->container === null) {
            $builder = new ContainerBuilder();
            $builder->addDefinitions($this->definition);
            foreach ($this->modules as $module) {
                if ($module::DEFINITIONS) {
                    $builder->addDefinitions($module::DEFINITIONS);
                }
            }
            $this->container = $builder->build();
        }
        return $this->container;
    }
}

index. php :

<?php
use Framework\App;
use App\Blog\BlogModule;
use App\Admin\AdminModule;
use GuzzleHttp\Psr7\ServerRequest;
use Framework\Middleware\{
    MethodMiddleware,
    RouterMiddleware,
    NotFoundMiddleware,
    DispatcherMiddleware,
    TrailingSlashMiddleware
};

require dirname(__DIR__) . '/vendor/autoload.php';

$modules = [
    AdminModule::class,
    BlogModule::class
];

$app = (new App((dirname(__DIR__) . '/config/config.php')))
    ->addModule(AdminModule::class)
    ->addModule(BlogModule::class)
    ->pipe(Middlewares\Whoops::class)
    ->pipe(TrailingSlashMiddleware::class)
    ->pipe(MethodMiddleware::class)
    ->pipe(RouterMiddleware::class)
    ->pipe(DispatcherMiddleware::class)
    ->pipe(NotFoundMiddleware::class);

if (php_sapi_name() !== "cli") {
    $response = $app->run(ServerRequest::fromGlobals());
    \Http\Response\send($response);
}

Ce que j'obtiens

Fatal error: Uncaught RuntimeException: No PSR-17 factory detected to create a response in C:\Users\perrot\Documents\MonFramework\vendor\middlewares\utils\src\FactoryDiscovery.php on line 178
( ! ) RuntimeException: No PSR-17 factory detected to create a response in C:\Users\perrot\Documents\MonFramework\vendor\middlewares\utils\src\FactoryDiscovery.php on line 178

3 réponses


Curvata
Réponse acceptée

J'ai trouvé le problème, "franzl/whoops-middleware" et "middlewares/whoops" lance une fonction static Factory::getResponseFactory() de la class "Factory" dans le dossier "middlewares/utils" si on remonte l'ensemble des statics on arrive sur la class "FactoryDiscovery" et j'ai remarqué la constante public const GUZZLE = '\GuzzleHttp\Psr7\HttpFactory'; Ce fichier n'existe pas dans mon dossier \GuzzleHttp\Psr7\ pourtant sur le dépot Github dans la version 1.7 le fichier est bien présent https://github.com/guzzle/psr7/blob/master/src/HttpFactory.php mais dans ma version 1.7 dans ma config je n'ai rien et donc j'ai simplement crée un fichier "HttpFactory" dans mon dossier "\GuzzleHttp\Psr7\" avec le contenu du fichier que j'ai récupéré sur le GitHub de Guzzle. Je sais qu'il ne faut pas toucher au dosssier "vendor" mais c'est la seul solution que j'ai trouvé pour l'instant et je ne sais pas pourquoi le fichier n'est pas présent dans le dossier à la base.

Il faudra aussi penser à mettre ton require dirname(__DIR__) . '/vendor/autoload.php';au début de ton fichier avant les use.

ça fonctionne, bien vu !
Merci d'avoir partagé ta solution