How to pass PDO to other objects in MVC OOP application

Asked

Viewed 385 times

2

I’m developing a small framework for learning purposes, and one of the ways I found to pass the PDO object to be used in controllers/models was using the following approach:

The constructor method of the parent controller receives a PDO object, and this is inherited by all the "Controllers sons", who also inherit the "loadModel" method, which returns an object already with the PDO that was passed as argument in the parent Controller.

.

DOUBT: Is this a good approach? otherwise, why? what are the advantages and disadvantages? and what would be a good alternative?

COMPLEMENT: I did some research and it seems that the appropriate Pattern for this would be the Factory, but I do not know how would be its implementation in my code so that it is available for all controllers, even those that do not use connection to the database.

If possible, exemplify based on my code

Connection.php

<?php

$options = array(
    PDO::ATTR_EMULATE_PREPARES => false,
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::MYSQL_ATTR_FOUND_ROWS => true
    );

$connection = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='. DB_CHARSET, DB_USER, DB_PASS, $options);

return $connection;

index php.

// has some validations and route URL handling (controller - action) and sets the controller in the $controller variable, and it receives, through the constructor, the PDO object to be used within the method.

$obj = new $controller($connection);

controller.php (Parent controller)

class Controller {

private $connection;

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

public function loadModel ($model) {
    return new $model($this->connection);
}

Usercontroller.php (example controller)

class UserController extends Controller {

    function registration () {

            $useCRUD = $this->loadModel('userCRUD');

            $info = array('name' => 'Joao', 'age' => 25);

            $userCRUD->create($info);
        }

}

userCRUD.php Receives the PDO object from the constructor and makes the CRUD interactions with the database.

  • 1

    Why don’t you use the Singleton standard? It ensures only one instance of a class, in which case it would be your connection to the bank. Then I wouldn’t need all this structure.

  • But Singleton is not an "anti-standard"?

1 answer

1

Creating the controllers

Factorys can be used to solve the problem, so they will be passed to a class that will run the controllers checking if there is any Factory for their creation.

The implementation of Factory would look something like this:

class UserControllerFactory
{
    // OBS: O método __invoke faz uma classe poder ser executada como uma função do PHP.
    public function __invoke()
    {    
         $userCrud = new UserCrud(PDOFactory::create());
         return new UserController($userCrud);
    }
}

The class that will run your controllers would look like this:

class ControllerInitializer
{

    private $factorys;

    public function __construct(
        array $factorys
    ){

        $this->factorys = $factorys;

    }

    public function init($controller, $action)
    {

        if(isset($this->factorys[$controller])){
             $factory    = $this->factorys[$controller];
             $controller = $factory();
             $controller->$action();
        }else{
            // Caso o controller não seja encontrado é um erro 404.
        }

    }

}
  • I think now gave a whitened, I just did not understand very well the use of __invoke(), and besides the Usercontrollerfactory I would have another Usercontroller or could already use it in a normal way? with the methods Registration etc, and within these methods would have to open a Pdofactory as well?

  • and taking advantage of the above comment from @João Pedro, a solution could be to pass the PDO using Singleton? directly in the model call, for example: $userModel = new userModel(PDOFactory::getInstance());

Browser other questions tagged

You are not signed in. Login or sign up in order to post.