PHP-DI 按名称注入参数
PHP-DI inject parameter by name
我正在同时使用 php-di 和 Doctrine。要使用 Doctrine,有一个构建 $entityManager
对象的 bootstrap.php
文件。 $entityManager
对象在该文件中全局定义,因此要在我的 classes 中使用它,我必须注入它。
例如假设下面的 class:
<?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;
}
}
}
?>
但是 $entityManager
的类型没有明确定义,当我调用 echo gettype($entityManager);
时它会打印 "object"
作为结果。所以我想我需要通过它的名称而不是它的类型来注入这个参数。我的意思是这样的:
$container->set('$entityManager', $entityManager);
但这不起作用。解决方案和最佳方法是什么?
你能展示一下你现在是如何注入 EntityManager 的吗?
此外,使用类型提示是一个好习惯:
public function __construct(EntityManager $entityManager) {
$this->entityManager = $entityManager;
}
更新:
好的,我通常使用 PHP-DI 和 PHP 配置文件 (http://php-di.org/doc/php-definitions.html)。它看起来像这样:
return [
AccountService::class => DI\object(AccountService::class)->constructor("here goes EntityManager object")
];
遇到this link显示$entityManager
的命名空间和class名称后问题已经解决,但是根据变量名注入的问题仍然悬而未决。现在我的新源码是这样的:
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');
}
?>
我正在同时使用 php-di 和 Doctrine。要使用 Doctrine,有一个构建 $entityManager
对象的 bootstrap.php
文件。 $entityManager
对象在该文件中全局定义,因此要在我的 classes 中使用它,我必须注入它。
例如假设下面的 class:
<?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;
}
}
}
?>
但是 $entityManager
的类型没有明确定义,当我调用 echo gettype($entityManager);
时它会打印 "object"
作为结果。所以我想我需要通过它的名称而不是它的类型来注入这个参数。我的意思是这样的:
$container->set('$entityManager', $entityManager);
但这不起作用。解决方案和最佳方法是什么?
你能展示一下你现在是如何注入 EntityManager 的吗?
此外,使用类型提示是一个好习惯:
public function __construct(EntityManager $entityManager) {
$this->entityManager = $entityManager;
}
更新:
好的,我通常使用 PHP-DI 和 PHP 配置文件 (http://php-di.org/doc/php-definitions.html)。它看起来像这样:
return [
AccountService::class => DI\object(AccountService::class)->constructor("here goes EntityManager object")
];
遇到this link显示$entityManager
的命名空间和class名称后问题已经解决,但是根据变量名注入的问题仍然悬而未决。现在我的新源码是这样的:
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');
}
?>