**SOLVED** Injecting the $container object into a class handling a route

Hi all,

i am learning the ins and outs of Slim Framework. For the purposes of illustrating the problem, I am trying to return the details of a user ID in json format.

routes.php

use Slim\App;

return function (App $app) {
$app->get('/user/{userID}', 'Gpmfg\User\User');
};

User.php

namespace Gpmfg\User;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class User{

  public function __construct(){
  }
  public function __invoke(Request $request, Response $response, $args){
    $response->getBody()->write(json_encode(array("id" => $args['userID'], "name" => 'Bob User')));
    return $response->withHeader('Content-Type', 'application/json');
  }
}

Very basic example, but it works. Where I am stuck is I have PDO settings defined in my settings.php:

settings.php
use DI\ContainerBuilder;

return function (ContainerBuilder $containerBuilder) {
  // Application specific settings
  $containerBuilder->addDefinitions([
    "db" => [
      "host"   => "mysql:host=myhost",
      "user"   => "mydb",
      "pw"     => "mypw",
      "config" => []
    ]
  ]);
};

I would like to insert a PDO object into my user class as defined above, where my __invoke would query the database for details and return them. How do I get a PDO object into my user class? I tried passing in the $container object to the __construct function, but I got the following error

Entry \"Gpmfg\\User\\User\" cannot be resolved: Parameter $container of __construct() has no value   defined or guessable
Full definition:
Object (class = Gpmfg\\User\\User lazy = false __construct( $container = #UNDEFINED

Thank you.

Hello @jordanr

You should add an container defintion for PDO::class. Read more

Example:

PDO::class => function (ContainerInterface $container) {
    // load database settings
    $settings = $container->get('settings')['db'];

    $host = $settings['host'];
    $dbname = $settings['database'];
    $username = $settings['username'];
    $password = $settings['password'];
    $charset = $settings['charset'];
    $flags = $settings['flags'];
    $dsn = "mysql:host=$host;dbname=$dbname;charset=$charset";

    // create and return PDO instance
    return new PDO($dsn, $username, $password, $flags);
},

Then in your class add PDO to the constructor:

use PDO;

class User
{
  private $pdo;

  public function __construct(PDO $pdo)
  {
     $this->pdo = $pdo;
  }

  public function __invoke(Request $request, Response $response, $args)
  {
    $rows = $this->pdo->...;

    $response->getBody()->write(json_encode(array("id" => $args['userID'], "name" => 'Bob User')));
    return $response->withHeader('Content-Type', 'application/json');
  }
}

@odan,

Thank you! That worked perfectly. So going forward, I just need to make sure I have a definition for any class I want to inject. That makes perfect sense. I appreciate your help!

1 Like