lost111in lost111in - 4 months ago 70
PHP Question

Slim controller issue : must be an instance of ContainerInterface, instance of Slim\\Container given

I am trying to use controller in Slim however keep getting the error

PHP Catchable fatal error: Argument 1 passed to

TopPageController::__construct() must be an instance of ContainerInterface,

instance of Slim\Container given

My index.php

<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

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

spl_autoload_register(function ($classname) {
require ("../classes/" . $classname . ".php");
});

$app = new \Slim\App(["settings" => $config]);
$app->get('/', function (Request $request, Response $response) {
$response->getBody()->write("Welcome");
return $response;
});
$app->get('/method1', '\TopPageController:method1');
$app->run();
?>


My TopPageController.php

<?php
class TopPageController {
protected $ci;
//Constructor
public function __construct(ContainerInterface $ci) {
$this->ci = $ci;
}

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

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

public function method3($request, $response, $args) {
//your code
//to access items in the container... $this->ci->get('');
$response->getBody()->write("Welcome3");
return $response;
}
}
?>


Thanks. I am using Slim 3.

Answer

Your code seems to be based on the Slim 3 documentation at http://www.slimframework.com/docs/objects/router.html that contains the type declaration (type hinting) error.

@geggleto is correct, you need to change the constructor of the TopPageController to:

public function __construct(Interop\Container\ContainerInterface $ci) {
    $this->ci = $ci;
}

The reason is that the Slim\Container class is using the Interop\Container\ContainerInterface interface (see the source code):

use Interop\Container\ContainerInterface;

Since Slim\Container is extending Pimple\Container, the following should all be valid (working) type declarations for your controller's method:

public function __construct(Pimple\Container $ci) {
    $this->ci = $ci;
}

...or even...

public function __construct(ArrayAccess $ci) {
    $this->ci = $ci;
}