Bonjour , j'ai ce probleme la qui ne retrouve pas la Classe Controller.php, mais je ne sais pas si le probleme vient directory separator que j'ai utilise

ici --> Class Dispatcher
    function __construct()
    {
        $this->request = new Request();
        Router::parse($this->request->url, $this->request);
        $controller = $this->loadController();
        $controller->view();
    }

    function loadController() {
        $name = ucfirst($this->request->controller).'Controller';
        $file =  dirname(__DIR__). DIRECTORY_SEPARATOR . 'controller' . DIRECTORY_SEPARATOR . $name . '.php';
        require $file;
        return new $name($this->request);

    }
}

Classe PagesController
celui de Controller est dans mon includes.php qui a son tour est appeller dans le dispatcher

<?php

class PagesController extends Controller {

    function view() {
        echo 'Vous voyez?';
    }

}

Ce que j'obtiens

Voila le message d'erreur (https://drive.google.com/file/d/129atVQtEGjBgkFlA8cQZWTtv9Z3doVK4/view?usp=share_link) et ce qui m'intrigue c'est le fait d'afficher ceci
'C:\wamp64\www\jonapack\controller\JonapackController.php puisque apres \controller jonapack ne devrait plus etre la

4 réponses


quenti77
Réponse acceptée

Hello,

Première chose, je te conseil de mettre la visibilité aussi sur tes méthodes de classe.

Ensuite tu suis un tuto en particulier ou tu essaye de ton côté de le faire ? Car je trouve que ça part un peu dans tous les sens entre des instanciations dans le constructeur, du statique et la création de données à droite et à gauche.

Comme on ne voit pas comment marche le parse de ton router ça va être dur d'imaginer mais j'ai du coup peut-être que l'erreur est là-bas.

Le controller :

namespace Tuto\Controller;

class PagesController extends Controller
{
    public function view(): void
    {
        echo "Hello World!"; // Just for debug, don't echo in a class
    }
}

Puis on représente une requête :

namespace Tuto;

class Request
{
    public function __construct(
        private readonly string $method,
        private readonly string $uri,
    ) {
    }

    public static function fromGlobals()
    {
        return new self(
            method: strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET'),
            uri: $_SERVER['REQUEST_URI'] ?? '/',
        );
    }

    public function getMethod(): string
    {
        return $this->method;
    }

    public function getUri(): string
    {
        return $this->uri;
    }
}

Puis on a notre router avec la représentation d'une route

namespace Tuto;

class Router
{
    /** @var Route[] $routes */
    private array $routes = [];

    public function add(string $method, string $path, string $controller, string $action): void
    {
        $this->routes[] = new Route($method, $path, $controller, $action);
    }

    public function match(Request $request): Route
    {
        foreach ($this->routes as $route) {
            if ($route->match($request)) {
                return $route;
            }
        }
        throw new \Exception('No matching route');
    }
}
namespace Tuto;

class Route
{
    public function __construct(
        public readonly string $method,
        public readonly string $path,
        public readonly string $controller,
        public readonly string $action,
    ) {
    }

    public function match(Request $request): bool
    {
        return $this->method === $request->getMethod() && $this->path === $request->getUri(); // Change for better matching
    }
}

Enfin ton dispatcher qui utilise les classes précédentes et non pas qui y sont dépendante :

namespace Tuto;

class Dispatcher
{
    public function __construct(
        private readonly Router $router,
    ) {
    }

    public function dispatch(Request $request): void
    {
        $route = $this->router->match($request);

        $controllerName = $route->controller;
        $controller = new $controllerName();
        $controller->{$route->action}();
    }
}

Et du coup l'utilisation donnerai :

use Tuto\Dispatcher;
use Tuto\Request;
use Tuto\Route;
use Tuto\Router;
use Tuto\Controller\PagesController;

$router = new Router();
$router->add('GET', '/', PagesController::class, 'view');

$dispatcher = new Dispatcher($router);
$dispatcher->dispatch(Request::fromGlobals());

Comme on peut le voir je ne suis pas contre le statique mais il faut que ça servent vraiment les intérêts. La par exemple ça évite de gérer une création complexe d'un objet Request en utilisant ce que php nous mets à disposition.

Je te laisse voir un peu le code et poser les questions nécessaire sachant que je n'ai pas testé ce dernier mais c'est pour le principe de base. Je te conseil aussi de voir un peu le principe S.O.L.I.D. (https://essential-dev-skills.com/poo/principe-solid ou encore https://guillaume-richard.fr/principe-solid-simplifies-avec-des-exemples-en-php/)

Wilnbsi
Auteur

S'il vous plait

J'ai l'impression que Dispatcher est dans un dossier wilfried et que le controlleur est dans un dossier controller au même niveau donc il faudrait ptt changer
$file = dirname(__DIR__). DIRECTORY_SEPARATOR . 'controller' . DIRECTORY_SEPARATOR . $name . '.php';

en

$file = dirname(__DIR__). DIRECTORY_SEPARATOR . '../controller' . DIRECTORY_SEPARATOR . $name . '.php';

Tu peux préciser dans quel dossier (chemin complet) est le fichier JonapackController.php dans ton projet ?

Wilnbsi
Auteur

justement je n'ai pas un fichier JonapackController.php mais plutot PagesController.php dans controller