phpdependency-injectiondoctrine-ormphp-di

PHP-DI inject parameter by name


I am using php-di and Doctrine together. To use Doctrine there is a bootstrap.php file which constructs the $entityManager object. The $entityManager object is defined globally in that file so to use it in my classes I have to inject it.

For example assume the class below:

<?php
interface IAccountService{
    function login(string $username, string $password);
}
class AccountService implements IAccountService {

    private $entityManager;

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

    public function login(string $email, string $password){
        $q = $this->entityManager->createQueryBuilder()
            ->select('us.id, us.name, us.email, us.passwordHashed')
            ->from('User', 'us')
            ->where('us.email = ?1 AND us.passwordHashed = ?2')
            ->setMaxResults( '1' )
            ->setParameter(1,$email)
            ->setParameter(2, HASHHELPER::hashPasswordSHA512($password, $email))
            ->getQuery();

        // echo $q->getSql();

        $users = $q->getResult();

        // print_r($users);

        if(!empty($users) && count($users) > 0){
            $_SESSION["USER"] = $users[0];
            return true;
        }
        else{
            return false;
        }
    }
}
?>

But the type of $entityManager is not well defined and either when I call echo gettype($entityManager); it prints "object" as result. So I think I need to inject this parameter by its name instead of its type. I mean something like this:

$container->set('$entityManager', $entityManager);

But this does not work. What's the solution and the best way?


Solution

  • The problem have solved after facing this link which shows the namespace and class name of $entityManager but the question of injecting according to variable name is still open. By now, the new source code of mine is like this:

    AccountService.php

    <?php
    interface IAccountService{
        function login(string $username, string $password);
    }
    class AccountService implements IAccountService {
    
        private $entityManager;
    
        public function __construct(Doctrine\ORM\EntityManagerInterface $entityManager) {
            $this->entityManager = $entityManager;
        }
    
        public function login(string $email, string $password){
            $q = $this->entityManager->createQueryBuilder()
                ->select('us.id, us.name, us.email, us.passwordHashed')
                ->from('User', 'us')
                ->where('us.email = ?1 AND us.passwordHashed = ?2')
                ->setMaxResults( '1' )
                ->setParameter(1,$email)
                ->setParameter(2, HASHHELPER::hashPasswordSHA512($password, $email))
                ->getQuery();
    
            // echo $q->getSql();
    
            $users = $q->getResult();
    
            // print_r($users);
    
            if(!empty($users) && count($users) > 0){
                $_SESSION["USER"] = $users[0];
                return true;
            }
            else{
                return false;
            }
        }
    }
    ?>
    

    routes.php

    <?php
      spl_autoload_register(function ($class_name) {
        switch ($class_name){
          case 'AccountController':
            require_once 'controllers/account_controller.php';
            break;
          case 'AccountService':
          case 'IAccountService':
            require_once 'services/account_service.php';
            break;
          case 'URLHELPER':
            require_once 'helpers/URLHELPER.php';
            break;
          case 'STRINGHELPER':
            require_once 'helpers/STRINGHELPER.php';
            break;
          case 'HASHHELPER':
            require_once "helpers/HASHHELPER.php";
            break;
          case 'User':
            require_once "models/entities/user.php";
            break;
        }
      });
    
      function call($controller, $action) {
        global $entityManager;
        $container = DI\ContainerBuilder::buildDevContainer();
        $container->set('IAccountService', \DI\object('AccountService'));
        $container->set('Doctrine\ORM\EntityManagerInterface', $entityManager);
    
        // require the file that matches the controller name
        require_once('controllers/' . $controller . '_controller.php');
    
        // create a new instance of the needed controller
        switch($controller) {
          case 'home':
            $controller = $container->get('HomeController');
            break;
          case 'account':
            $controller = $container->get('AccountController');
            break;
          default:
            $controller = 'home';
            $action = 'index';
        }
    
        // call the action
        $controller->{ $action }();
      }
    
      // just a list of the controllers we have and their actions
      // we consider those "allowed" values
      $controllers = array(
        'home' => ['index', 'error']
        ,'account' => ['login']
      );
    
      // check that the requested controller and action are both allowed
      // if someone tries to access something else he will be redirected to the error action of the pages controller
      if (array_key_exists($controller, $controllers)) {
        if (in_array($action, $controllers[$controller])) {
          call($controller, $action);
        } else {
          call('home', 'error');
        }
      } else {
        call('home', 'error');
      }
    ?>