popop
popop

Reputation: 177

How to access to Slim container from other classess?

Suppose that in my dependencies.php file I setup this container:

<?php

$container = $app->getContainer();

$container['db'] = function($config)
{
  $db = $config['settings']['db'];
  $pdo = new PDO("mysql:host=" . $db['host'] . ";port=" . $db['port'] .
  ";dbname=" . $db['dbname'] . ";charset=" . $db['charset'], $db['user'], $db['pass']);
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
  return $pdo;
};

I can use this container inside my route, called for example table.php:

<?php

use Slim\Http\Request;
use Slim\Http\Response;

$app->get('/table/get_table', function (Request $request, Response $response, array $args)
{
  $sql = $this->db->prepare("SELECT * FROM some_table");
  $sql->execute();
  $result = $sql->fetchAll();
  return $response->withJson($result);
});

this is basically the default usage, right? Said that, how can I instead use the db container from other classes? Supposes I have created a class called TableUtility and imported inside the table.php:

class TableUtility
{
    function GetTableFromDb()
    {
       $sql = $this->db->prepare("SELECT * FROM some_table");
       $sql->execute();
       $result = $sql->fetchAll();
       return $response->withJson($result);
    }
}

as you can see I moved the logic of PDO inside GetTableFromDb of TableUtility, how can I access to db container from this class? The usage in table.php will be:

<?php

use Slim\Http\Request;
use Slim\Http\Response;

$app->get('/table/get_table', function (Request $request, Response $response, array $args)
{
  $tableUtility = new TableUtility();
  return $response->withJson($tableUtility->GetTableFromDb());
});

actually I get in TableUtility:

Call to a member function prepare() on null

Upvotes: 1

Views: 1052

Answers (1)

Nima
Nima

Reputation: 3409

The full name for what you refer to as container is Dependency Injection Container. It is supposed to contain dependencies for objects. Passing this container to objects is considered bad practice. Instead you should pass only required dependencies for that object, which in your case is to pass db to $tableUtility. This is usually used by passing dependencies when constructing the object, or using setter methods. In your case you can refactor your code like this:

class TableUtility
{
    function __construct($db) {
        $this->db = $db;
    }
}

Now in any method of TableUtility class, you have access to db object using $this->db but you'll need to pass db to class constructor whenever you create a new object. So you also need to do this:

$app->get('/table/get_table', function (Request $request, Response $response, array $args)
{
  $tableUtility = new TableUtility($this->db);
  // rest of the code
});

Upvotes: 4

Related Questions