Bonjour,

Voila je rencontre un petit problème avec mon code.

Ce que je fais

Décrivez ici votre code ou ce que vous cherchez à faire

<?php
/**
 * Created by IntelliJ IDEA.
 * User: MAXIME EPOH
 * Date: 03/03/2018
 * Time: 22:03
 */

namespace Framework {

    use Exception;
    use GuzzleHttp\Psr7\Response;
    use Psr\Container\ContainerInterface;
    use Psr\Http\Message\ResponseInterface;
    use Psr\Http\Message\ServerRequestInterface;

    class App
    {

        /**
         * @var array
         *List of modules
         */
        private $modules = [];

        /**
         * Container
         * @var ContainerInterface
         */
        private $container;

        /**
         * App constructor.
         * @param string[] $modules Liste des modules à charger
         * @throws \Psr\Container\ContainerExceptionInterface
         * @throws \Psr\Container\NotFoundExceptionInterface
         */
        public function __construct(array $modules = [])
        {
            $container = $this->container;
            foreach ($modules as $module) {
                $this->modules[] = $container->get($module);
            }
        }

        /**
         * @param ServerRequestInterface $request
         * @return ResponseInterface
         * @throws Exception
         * @throws \Psr\Container\ContainerExceptionInterface
         * @throws \Psr\Container\NotFoundExceptionInterface
         */
        public function run(ServerRequestInterface $request): ResponseInterface
        {
            $uri = $request->getUri()->getPath();
            if (!empty($uri) && $uri[-1] === "/") {
                return (new Response())
                    ->withStatus(301)
                    ->withHeader('Location', substr($uri, 0, -1));
            }
            $router = $this->container->get(Router::class);
            $route = $router->match($request);
            if (is_null($route)) {
                return new Response(404, [], '<h1>Erreur 404</h1>');
            }
            $params = $route->getParams();
            $request = array_reduce(array_keys($params), function ($request, $key) use ($params) {
                return $request->withAttribute($key, $params[$key]);
            }, $request);
            $response = call_user_func_array($route->getCallback(), [$request]);
            if (is_string($response)) {
                return new Response(200, [], $response);
            } elseif ($response instanceof ResponseInterface) {
                return $response;
            } else {
                throw new Exception('The response is not a string or an instance of ResponseInterface');
            }
        }
    }
}

Ce que je veux

Faire marcher l'appli sur le navigateur.

Ce que j'obtiens

Fatal error: Uncaught TypeError: Argument 1 passed to Framework\App::construct() must be of the type array, object given, called in C:\WebPages\MonFramework\public\index.php on line 28 and defined in C:\WebPages\MonFramework\src\Framework\App.php:38 Stack trace: #0 C:\WebPages\MonFramework\public\index.php(28): Framework\App->construct(Object(DI\Container), Array) #1 {main} thrown in C:\WebPages\MonFramework\src\Framework\App.php on line 38

13 réponses


Diarill
Auteur
Réponse acceptée

Là je ne sais plus quoi faire. je suis cette cinquième vidéo de puis quelques jours avec un oeil plus que sculteur, mais je tombe toujours sur cette erreure et je ne peux pas avancer tant que je ne comprends pas pourquoi.

Salut,
Je pense que tu lui a bien passé les 2 paramètres dans le index.php donc le tableau de module et le container mais tu as dû oublier de déclarer le container comme paramètre de ton constructeur dans ton App.php.

Et d'ailleurs lorsque tu veux assigner un paramètre de ton constructeur ou autre à une propriété de ta classe, c'est cette syntaxe et non l'inverse:

$this->container = $container;
Diarill
Auteur

<?php
/**

  • Created by IntelliJ IDEA.
  • User: MAXIME EPOH
  • Date: 03/03/2018
  • Time: 22:03
    */

namespace Framework {

use Exception;
use GuzzleHttp\Psr7\Response;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class App
{

    /**
     * @var array
     *List of modules
     */
    private $modules = [];

    /**
     * Container
     * @var ContainerInterface
     */
    private $container;

    /**
     * App constructor.
     * @param string[] $modules Liste des modules à charger
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function __construct(array $modules = [])
    {
        $this->container = $container;
        foreach ($modules as $module) {
            $this->modules[] = $container->get($module);
        }
    }

    /**
     * @param ServerRequestInterface $request
     * @return ResponseInterface
     * @throws Exception
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function run(ServerRequestInterface $request): ResponseInterface
    {
        $uri = $request->getUri()->getPath();
        if (!empty($uri) && $uri[-1] === "/") {
            return (new Response())
                ->withStatus(301)
                ->withHeader('Location', substr($uri, 0, -1));
        }
        $router = $this->container->get(Router::class);
        $route = $router->match($request);
        if (is_null($route)) {
            return new Response(404, [], '<h1>Erreur 404</h1>');
        }
        $params = $route->getParams();
        $request = array_reduce(array_keys($params), function ($request, $key) use ($params) {
            return $request->withAttribute($key, $params[$key]);
        }, $request);
        $response = call_user_func_array($route->getCallback(), [$request]);
        if (is_string($response)) {
            return new Response(200, [], $response);
        } elseif ($response instanceof ResponseInterface) {
            return $response;
        } else {
            throw new Exception('The response is not a string or an instance of ResponseInterface');
        }
    }
}

}

<?php

  • Created by IntelliJ IDEA.
  • User: MAXIME EPOH
  • Date: 03/03/2018
  • Time: 21:59
    */
    /**

use App\blog\BlogModule;
use Framework\App;
use GuzzleHttp\Psr7\ServerRequest;

require "../vendor/autoload.php";

$modules = [
BlogModule::class,
];
$builder = new \DI\ContainerBuilder();
$builder->addDefinitions(dirname(DIR) . '/config/config.php');
$builder->addDefinitions(dirname(DIR) . '/config.php');
foreach ($modules as $module) {
if($module::DEFINITIONS) {
$builder->addDefinitions($module::DEFINITIONS);
}
}
$container = $builder->build();

$app = new App($container, $modules);
$response = $app->run(ServerRequest::fromGlobals());
\Http\Response\send($response);

J'écris le même code que Grafikart, mais là il ne se passe rien. Poooorrrr...même message d'érreure

Alors déjà, lorsque tu fais ton $container->addDefinitions();, ce n'est pas DIRmais __DIR__ la constante, ensuite dans ta classe App.php, dans le constructeur, tu as oublié d'ajouter le container en paramètre, normalement ton constructeur devrait ressembler à ça:

    /**
     * App constructor.
     * @param ContainerInterface $container
     * @param string[] $modules Liste des modules à charger
     */
    public function __construct(ContainerInterface $container, array $modules = [])
    {
        $this->container = $container;
        foreach ($modules as $module) {
            $this->modules[] = $container->get($module);
        }
    }

Et n'oublies pas d'importer la classe ContainerInterface.

Bonjour.

ce n'est pas DIR mais __DIR__.

Je ne cherche pas à l'excuser de son erreur, mais je ne pense pas qu'il ce soit trompé, il a du bienj mettre __DIR__, mais comme il a mal formatté son code dans le contenu de son message, les caractères _ ont été interprété et comme deux _ permet de formater du texte en gras, c'est ce que ça à fait.

@Diarill: Comme je l'ai dit, ça ne t'excuses pas du fait que tu as mal formatté ton code, penses à vérifier le contenu de tes messages quand tu les valide, quitte à raffraîchir la page pour t'en assurer, ceci évitera des malentendu de lecture et nous permettra de pouvoir mieux t'aider en ayant un meilleur visuel de tes codes.

Diarill
Auteur
Là je vous présente le code tel que sur la video de Grafikart
Diarill
Auteur
<?php
/**
 * Created by IntelliJ IDEA.
 * User: MAXIME EPOH
 * Date: 03/03/2018
 * Time: 22:03
 */

namespace Framework {

    use Exception;
    use GuzzleHttp\Psr7\Response;
    use Psr\Container\ContainerInterface;
    use Psr\Http\Message\ResponseInterface;
    use Psr\Http\Message\ServerRequestInterface;

    class App
    {

        /**
         * @var array
         *List of modules
         */
        private $modules = [];

        /**
         * Container
         * @var ContainerInterface
         */
        private $container;

        /**
         * App constructor.
         * @param ContainerInterface $container
         * @param string[] $modules Liste des modules à charger
         * @throws \Psr\Container\ContainerExceptionInterface
         * @throws \Psr\Container\NotFoundExceptionInterface
         */
        public function __construct(array $modules = [])
        {
            $this->container = $container;
            foreach ($modules as $module) {
                $this->modules[] = $container->get($module);
            }
        }

        /**
         * @param ServerRequestInterface $request
         * @return ResponseInterface
         * @throws Exception
         * @throws \Psr\Container\ContainerExceptionInterface
         * @throws \Psr\Container\NotFoundExceptionInterface
         */
        public function run(ServerRequestInterface $request): ResponseInterface
        {
            $uri = $request->getUri()->getPath();
            if (!empty($uri) && $uri[-1] === "/") {
                return (new Response())
                    ->withStatus(301)
                    ->withHeader('Location', substr($uri, 0, -1));
            }
            $router = $this->container->get(Router::class);
            $route = $router->match($request);
            if (is_null($route)) {
                return new Response(404, [], '<h1>Erreur 404</h1>');
            }
            $params = $route->getParams();
            $request = array_reduce(array_keys($params), function ($request, $key) use ($params) {
                return $request->withAttribute($key, $params[$key]);
            }, $request);
            $response = call_user_func_array($route->getCallback(), [$request]);
            if (is_string($response)) {
                return new Response(200, [], $response);
            } elseif ($response instanceof ResponseInterface) {
                return $response;
            } else {
                throw new Exception('The response is not a string or an instance of ResponseInterface');
            }
        }
    }
}
Diarill
Auteur
<?php
/**
 * Created by IntelliJ IDEA.
 * User: MAXIME EPOH
 * Date: 03/03/2018
 * Time: 21:59
 */

use App\blog\BlogModule;
use Framework\App;
use \GuzzleHttp\Psr7\ServerRequest;

require "../vendor/autoload.php";

$modules =  [ BlogModule::class ];

$builder = new \DI\ContainerBuilder();
$builder->addDefinitions(dirname(__DIR__) . '/config/config.php');
$builder->addDefinitions(dirname(__DIR__) . '/config.php');
foreach ($modules as $module) {
    if ($module::DEFINITIONS) {
        $builder->addDefinitions($module::DEFINITIONS);
    }
}
$container = $builder->build();

$app = new App($container, $modules);
$response = $app->run(ServerRequest::fromGlobals());
\Http\Response\send($response);
Diarill
Auteur

``

Erreur irrécupérable : TypeError non intercepté: L'argument 1 passé à Framework \ App :: construct () doit être du type array, objet donné, appelé dans C: \ WebPages \ MonFramework \ public \ index.php à la ligne 27 et défini dans C: \ Trace de pile: # 0 C: \ WebPages \ MonFramework \ public \ index.php (27): Framework \ App -> construct (Objet (DI \ Conteneur), Array ) # 1 {main} lancé dans C: \ WebPages \ MonFramework \ src \ Framework \ App.php à la ligne 39

Diarill
Auteur
Je vous prie de regarder ce que fait Grafikart dans la vidéo à partir de 19:05.
Merci pour votre soutien.

J'ai regardé la vidéo et il suffit de la suivre jusqu'à la fin puisque à un moment, comme je te l'ai dit depuis le début, il rajoute le paramètre container dans le constructeur de la classe App.php, j'ai téléchargé les sources.
Regarde à 23:07min.
De toute façon, il n'y a pas besoin de regarder la vidéo, l'erreur est claire, il s'attendait à avoir un objet de type ContainerInterface donc le container et il a reçu le tableau des modules, donc forcément les paramètres du constructeur de ta classe App ne sont pas bons.

Diarill
Auteur

Bonjour à tous. Comme je l'ai expliqué depuis le premier problème que j'ai rencontré au début de cette formation, je suis nouveau et plustôt que de faire un copier - coller, je suis l'ensemble des chapitres de bout en bout pour au mieux comprendre ce qui se fait et cela se fait. Ainsi je regarde au moins trois une vidéo avant de passer à la pratique.
Avant d'arriver à 23:07 où on voit qu'il a passé en paramètre ContainerInterface (container) dans le__construct de App.php, on peut quand même remarquer qu'il lance la simulation à 21:45; c'est là exactement que mon code me pose des problème. je suis allé plus loin dans la formation (23:07) où il passe en paramètre le ContainerInterface. Voilà le message que je reçoi, après avoir reécris tous les codes au moins 6 fois depuis hier :

Erreur fatale: Non interceptée DI \ Définition \ Exception \ InvalidDefinition: L'entrée "App \ blog \ BlogModule" ne peut pas être résolue: Paramètre $ renderer de construct () n'a pas de valeur définie ou devinable Définition complète: Object (class = App \ blog \ BlogModule lazy = false construct ($ préfixe = 'préfixe' $ router = obtenir (blog.prefix) $ renderer = # UNDEFINED #)) dans C: \ WebPages \ MonFramework \ fournisseur \ php-di \ php-di \ src \ Définition \ Exception \ InvalidDefinition .php: 18 Trace de pile: # 0 C: \ WebPages \ MonFramework \ fournisseur \ php-di \ php-di \ src \ Définition \ Resolver \ ObjectCreator.php (159): DI \ Définition \ Exception \ InvalidDefinition :: create ( Objet (DI \ Definition \ ObjectDefinition), 'Entrée' App \ blog ... ') # 1 C: \ WebPages \ MonFramework \ fournisseur \ php-di \ php-di \ src \ Définition \ Resolver \ ObjectCreator.php ( 73): DI \ Definition \ Resolver \ ObjectCreator->createInstance (Objet (DI \ Définition \ ObjectDefinition), Array) # 2 C: \ WebPages \ MonFramework \ fournisseur \ php-di \ php-di \ src \ Définition \ Resolver \ ResolverDispatcher.php (64): DI \ Définition \ Resolver \ ObjectC dansC: \ WebPages \ MonFramework \ fournisseur \ php-di \ php-di \ src \ Définition \ Exception \ InvalidDefinition.php à la ligne 18

Diarill
Auteur

Voici mon code jusqu'où tout marche bien. index.php; App.php et BlogModule.php

<?php
/**
 * Created by IntelliJ IDEA.
 * User: MAXIME EPOH
 * Date: 03/03/2018
 * Time: 21:59
 */

use App\blog\BlogModule;
use Framework\App;
use \GuzzleHttp\Psr7\ServerRequest;

require "../vendor/autoload.php";

$builder = new \DI\ContainerBuilder();
$builder->addDefinitions(dirname(__DIR__) . '/config/config.php');
$builder->addDefinitions(dirname(__DIR__) . '/config.php');
$container = $builder->build();

$app = new App($container, [
    BlogModule::class
]);
$response = $app->run(ServerRequest::fromGlobals());
\Http\Response\send($response);
<?php
/**
 * Created by IntelliJ IDEA.
 * User: MAXIME EPOH
 * Date: 03/03/2018
 * Time: 22:03
 */

namespace Framework {

    use Exception;
    use GuzzleHttp\Psr7\Response;
    use Psr\Container\ContainerInterface;
    use Psr\Http\Message\ResponseInterface;
    use Psr\Http\Message\ServerRequestInterface;

    class App
    {

        /**
         * @var array
         *List of modules
         */
        private $modules = [];

        /**
         * Container
         * @var ContainerInterface
         */
        private $container;

        /**
         * App constructor.
         * @param ContainerInterface $container
         * @param string[] $modules Liste des modules à charger
         * @throws \Psr\Container\ContainerExceptionInterface
         * @throws \Psr\Container\NotFoundExceptionInterface
         */
        public function __construct(ContainerInterface $container, array $modules = [])
        {
            $this->container = $container;
            foreach ($modules as $module) {
                $this->modules[] = $container->get($module);
            }
        }

        /**
         * @param ServerRequestInterface $request
         * @return ResponseInterface
         * @throws Exception
         * @throws \Psr\Container\ContainerExceptionInterface
         * @throws \Psr\Container\NotFoundExceptionInterface
         */
        public function run(ServerRequestInterface $request): ResponseInterface
        {
            $uri = $request->getUri()->getPath();
            if (!empty($uri) && $uri[-1] === "/") {
                return (new Response())
                    ->withStatus(301)
                    ->withHeader('Location', substr($uri, 0, -1));
            }
            $router = $this->container->get(Router::class);
            $route = $router->match($request);
            if (is_null($route)) {
                return new Response(404, [], '<h1>Erreur 404</h1>');
            }
            $params = $route->getParams();
            $request = array_reduce(array_keys($params), function ($request, $key) use ($params) {
                return $request->withAttribute($key, $params[$key]);
            }, $request);
            $response = call_user_func_array($route->getCallback(), [$request]);
            if (is_string($response)) {
                return new Response(200, [], $response);
            } elseif ($response instanceof ResponseInterface) {
                return $response;
            } else {
                throw new Exception('The response is not a string or an instance of ResponseInterface');
            }
        }
    }
}

<?php
/**

  • Created by IntelliJ IDEA.
  • User: MAXIME EPOH
  • Date: 05/03/2018
  • Time: 11:07
    */

namespace App\blog {

use App\Framework\Renderer\RendererInterface;
use Framework\Router;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class BlogModule
{

    private $renderer;

    /**
     * BlogModule constructor.
     * @param Router $router
     * @param RendererInterface $renderer
     */
    public function __construct(Router $router, RendererInterface $renderer)
    {
        $this->renderer = $renderer;
        $this->renderer->addPath('blog', __DIR__ . '/views');
        $router->get('/blog', [$this, 'index'], 'blog.index');
        $router->get('/blog/{slug:[a-z\-0-9]+}', [$this, 'show'], 'blog.show');
    }

    /**
     * @param Request $request
     * @return Response
     */
    public function index(Request $request): string
    {
        return $this->renderer->render('@blog/index');
    }

    /**
     * @param Request $request
     * @return string
     */
    public function show(Request $request): string
    {
        return $this->renderer->render('@blog/show', [
            'slug' => $request->getAttribute('slug')
        ]);
    }
}

}