Routes and Container Resolution


#1

Hi,

I’m new with Slim and I have some doubts about how to use. I have read the documentation about it but it is not clear to me. https://discourse.slimframework.com/t/controllers-using-container-resolution/342

Here is what I have got in my project folder:

-- public
-- | -- index.php
-- | -- .htaccess
-- Txartelak
-- | -- Controllers
-- | -- | -- txartelakController.php
-- dependencies.php
-- composer.json
-- routes.php
-- settings.php
-- vendor

composer.json

{
    "require": {
        "php": ">=5.5.0",
        "slim/slim": "^3.1",
        "slim/twig-view": "^2.0",
        "monolog/monolog": "^1.17"
    },
    "autoload": {
        "psr-4": {
            "Txartelak\\": "src/Txartelak"
        }
    }
}

index.php

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
use Txartelak\Controller\txartelakController;

require __DIR__ . '/../vendor/autoload.php';

// Instantiate the app
$settings = require __DIR__ . '/../settings.php';
$app = new \Slim\App($settings);

// Set up dependencies
require __DIR__ . '/../dependencies.php';

// Register routes
require __DIR__ . '/../routes.php';

// Run app
$app->run();

routes.php

use Slim\Http\Request;
use Slim\Http\Response;
use Txartelak\Controller\txartelakController;

$app->get('/berriakClas',  \txartelakController::class . ':berriak');

txartelakController.php

namespace Txartelak\Controller;

class txartelakController
{
   protected $container;

   // constructor receives container instance
   public function __construct(ContainerInterface $container) {
       $this->container = $container;
   }

   public function berriak($request, $response, $args) {
        // your code
        // to access items in the container... $this->container->get('');
        return $response;
   }

   public function contact($request, $response, $args) {
        // your code
        // to access items in the container... $this->container->get('');
        return $response;
   }
}

The problem is that if when go to mydomain.com/berriakClas i have a Slim application error: Callable txartelakController does not exist

¿What are I’m doing wrong?


#2

It doesn’t look like you have a src folder there though. I suspect you may want

"Txartelak\\": "Txartelak"

There could be other issues, but that one jumps out at me first. Run composer dump autoload -o after you make the change.


#3

Sorry, but my folder structure is this:

src
|-- public
|-- | -- index.php
|-- | -- .htaccess
|-- Txartelak
|-- | -- Controllers
|-- | -- | -- txartelakController.php
|-- dependencies.php
|-- composer.json
|-- routes.php
|-- settings.php
|-- vendor
logs
templates

Is now correct the autoload psr-4?


#4

No, the autoloader is relative to the vendor folder, not the enclosing folder. So in that structure it would still likely look like

"Txartelak\\": "Txartelak"

#5

I put as you told me and it does not work either.

This is what I have in autoload_psr4.php

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'Txartelak\\' => array($baseDir . '/Txartelak'),
    'Twig\\' => array($vendorDir . '/twig/twig/src'),
    'Slim\\Views\\' => array($vendorDir . '/slim/twig-view/src'),
    'Slim\\' => array($vendorDir . '/slim/slim/Slim'),
    'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
    'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
    'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
    'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
    'Interop\\Container\\' => array($vendorDir . '/container-interop/container-interop/src/Interop/Container'),
    'FastRoute\\' => array($vendorDir . '/nikic/fast-route/src'),
);

Is this file ok?

Thank for your help!


#6

Yes, that looks okay. In your routes.php I could be mistaken, but I think you want

$app->get('/berriakClas',  TxartelakController::class . ':berriak');

#7

Thank very much @tflight, now works well! :wink: