6

Hi i am new to slim i stuck on this anyone help please

routes.php

$app->get('/', 'UserController:index');

dependencis.php

$container['src\UserController'] = function ($container) {
    return new \src\UserController($container->get('settings'));
};

UserController.php

namespace App\Controllers;

use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use App\src\Controller;
class UserController extends Controller {
    public function index(Request $request, Response $response) {
        return $this->db;
    }
}

and controller.php

namespace App\src;

class Controller {
    protected $container;
    public function __construct($c) {
        $this->container = $c;
    }

    public function __get($property) {
        if($this->container->has($property)) {
            return $this->container->get($property);
        }
        return $this->{$property};
    }
}
Donald Duck
  • 8,409
  • 22
  • 75
  • 99
Shahzad Nasir
  • 168
  • 1
  • 2
  • 11
  • Are you sure you should return `new \src\UserController()` in your container, not `new \App\src\UserController`? – Georgy Ivanov Feb 14 '17 at 07:54
  • $container['src\UserController'] = function ($container) { return new \src\UserController(); }; here it is itry most of this by changing path \src\UserController(); and return new \src\UserController($contianer); – Shahzad Nasir Feb 14 '17 at 08:02
  • Hi @ShahzadNasir, I got a problem that looks like yours. May I get help from you for this: http://stackoverflow.com/questions/43449493/slim-framework-routing-http-requests-to-static-class-methods . Thanks – red Apr 17 '17 at 10:26

3 Answers3

14

As you have defined your route as:

$app->get('/', 'UserController:index');

Then you need to define your DI factory as:

$container['UserController'] = function ($container) {
    // return an instantiated UserController here.
};

You should also look up how namespaces and PSR-4's mapping of namespace name to directory work. In general there is never a src in a namespace name, but you do see a namespace such as App mapped to a directory call src in the Composer autoloader as specified in composer.json.

Usually, it looks something like this:

"autoload": {
    "psr-4": {
        "App\\": "src/"
    }
},

This means that you have a directory called src and any class inside that directory, will have a base namespace of App and then any other directories act as sub-namespaces.

i.e. if you have a file called src/Controllers/UserController.php, then the class definition in that file will be:

<?php
namespace App\Controllers;
class UserController
{
    // methods here
}

Note also that the capitalisation of the filename matches the class name and that the capitalisation of the directories match the capitalisation of the sub-namespaces.

To continue the example, I would expect the DI factory to look like this:

$container['UserController'] = function ($container) {
    return new \App\Controllers\UserController($container->get('settings'));
};

It's really unusual to see src in a namespace definition, so go through and check that your namespaces and files on disk all match up as the code in the question is inconsistent.

Rob Allen
  • 12,643
  • 1
  • 40
  • 49
  • 1
    @Rob worked for me too, and gave me a better understanding of how namespacing and auto loader works better than other manuals I read online. – Attis Jul 26 '19 at 23:14
2

You can check the name of the file (controller.php) that holds controller class. they must be the same.

for example :

if you have Contoller.php file you must make the name of class like this Controller.

in your example you have Controller.php file with capital letter of C but, the class controller doesn't start with a capital letter.

so, make sure the file name is same as the class name.

hope this will help you .

Mohammed_7aafar
  • 385
  • 1
  • 6
  • 9
  • 1
    Hi Mohammed, thanks for your response. Would you please clarify your sentence, "they must me same." Do you mean, "they must be the same"? I was going to correct this type-o; however, I realized that the statement is still very ambiguous. Please clarify, what must be the same? For example, do you mean the file names, directories, paths, classes, etc. or what? Also please don't mark your answer "resolved". The original poster will indicate if your answer has solved the question. – David John Coleman II Mar 14 '20 at 02:38
  • Hi David John, I really do appreciate your advices. – Mohammed_7aafar Mar 19 '20 at 06:48
0

in my case this is work, i hope for you too

home_controller.php

namespace Apa\Kabar;

use Psr\Container\ContainerInterface;

class HomeController
{
   protected $container;

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

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

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

route.php*


require __DIR__. '/../controller/home_controller.php';

$configuration = [
    'settings' => [
        'displayErrorDetails' => true,
    ],
];
$con = new Container($configuration);

$app = new App($con);
$con = $app->getContainer();

$con['HomeController'] = function($con) {
    return new HomeController($con);
};

$app->get('/home', 'HomeController:home');

malik kurosaki
  • 1,747
  • 15
  • 9