Slim 4 How to access PDO instance created in dependencies.php

I’m new to DI and have what I’m sure is a newbie question. How do I get the PDO connection in my model class that was created in dependicies.php?

I have Controller and Model classes.

My route:

$app->group('/users', function (Group $group) {
  $group->get('', [UsersController::class, 'getAll'], function (Request $request, Response $response) {
     return $response;
  });
});

My Controller:

namespace App\Application\Controllers;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use App\Application\Models\UsersService;

class UsersController
{

  private $_usersSvc;

  public function __construct()
  {
    $this->_usersSvc = new UsersService();
  }

  public function getAll(Request $request, Response $response)
  {
    $uri = $request->getUri();
    parse_str($uri->getQuery(), $params);
    $result = $this->_usersSvc->getAll($params);
    $response->getBody()->write(json_encode($result));

    return $response;
  }

My DI setup in dependencies.php

return function (ContainerBuilder $containerBuilder) {
    $containerBuilder->addDefinitions([
        LoggerInterface::class => function (ContainerInterface $c) {
            $settings = $c->get(SettingsInterface::class);

            $loggerSettings = $settings->get('logger');
            $logger = new Logger($loggerSettings['name']);

            $processor = new UidProcessor();
            $logger->pushProcessor($processor);

            $handler = new StreamHandler($loggerSettings['path'], $loggerSettings['level']);
            $logger->pushHandler($handler);

            return $logger;
        },
        PDO::class => function (ContainerInterface $c) {
            $settings = $c->get('settings');
            $db = [
              'dbname' => $settings['db']['name'],
              'user'   => $settings['db']['username'],
              'pass'   => $settings['db']['password'],
              'host'   => $settings['db']['host']
            ];
      
            $connection = new PDO("mysql:host=" . $db['host'] . ";port=3306;dbname=" . $db['dbname'], $db['user'], $db['pass']);
            $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
      
            return $connection;
          },        
    ]);
};

My Model Class

namespace App\Application\Models;

use App\Application\Models\DataObjects;
use Psr\Log\LoggerInterface;
use Psr\Container\ContainerInterface;
use DateTime;
use PDO;

class UsersService extends DataObjects
{
    protected $db;

    public function __construct()
    {   

    }

    public function getAll($params)
    {
        $orderBy = (isset($params['sortdesc']) && empty($params['sortdesc']) === false) ? $params['sortdesc'] . ' DESC' : null;
        if ($orderBy === null) {
            $orderBy = (isset($params['sortasc']) && empty($params['sortasc']) === false) ? $params['sortasc'] . ' ASC' : '';
        }

        return $this->loadAll($orderBy);
    }
}

How to access $connection instance from dependencies.php in my model class?

Hi @datazen

You need to declare all dependencies in the class constructor. You have to do it for all of your classes.

final class UsersController
{
    private $userService;

    public function __construct(UserService $userService)
    {
        $this->userService= $userService;
    }
}
final class UserService
{
    private $userRepository;

    public function __construct(UserRepository $userRepository)
    {   
        $this->userRepository = $userRepository;
    }
}
final class UserRepository
{
    private $connection;

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

Daniel,

Thank you very much for the quick response. When I try the solution, I get an error in the route file since I am not passing and params to the controller constructor.

Too few arguments to function App\\Application\\Models\\UsersService::__construct(), 0 passed

What would the route look like in my case?

Thanks again for your help.

This happens when you “manually” create the object instance without passing the required constructor parameters, e.g. $object = new UsersService(). Instead just let the DI container (e.g. PHP DI) do this job for you.

Dan,

Thank you very much for your help. All is working now. Old PHP habits die hard :wink:

1 Like