我尝试用PHP-DI创建一个项目,但我遇到了问题。
这是追踪:
以下是代码:
容器类:
$this->containerBuilder->addDefinitions([
'Configuration' => DI\Object('Hetwan\Core\Configuration')->constructor($this->getRootDir().'/app/config/config.yml'),
'Database' => DI\object('Hetwan\Core\Database')
]);
配置类:
namespace Hetwan\Core;
use Symfony\Component\Yaml\Yaml;
class Configuration
{
private $attrs;
public function __construct($configFilePath)
{
$this->attrs = Yaml::parse(file_get_contents($configFilePath));
}
public function get($attrPath)
{
$el = $this->attrs;
foreach (explode('.', $attrPath) as $attr)
{
if (!isset($el[$attr]))
throw new ConfigurationException("Unable to get '{$attrPath}'.\n");
$el = $el[$attr];
}
return $el;
}
}
数据库类:
namespace Hetwan\Core;
use Hetwan\Core\Configuration;
class Database
{
/**
* @Inject
* @var Configuration
*/
private $config;
private $entityManager;
public function create($entitiesPath)
{
$dbParameters = [
'driver' => 'pdo_mysql',
'user' => $config->get('database.user'),
'password' => $config->get('database.password'),
'dbname' => $config->get('database.name')
];
$this->entityManager = EntityManager::create($dbParameters, Setup::createAnnotationMetadataConfiguration([$entitiesPath], false));
}
public function getEntityManager()
{
return $this->entityManager;
}
}
我可以毫无问题地访问$container->get('Configuration')
并且有效。
但是在创建Database类时我认为PHP-DI尝试重新创建一个Configuration实例,我不知道为什么因为单例实例已经在这里了。
感谢您的帮助!
答案 0 :(得分:2)
注释<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body onload="loadHandler()">
<p>Drag me!</p>
<script type="text/javascript">
function loadHandler() {
document.getElementsByTagName('p').setAttribute('draggable', true);
}
</script>
</body>
</html>
很可能被解释为类名,基于文件的命名空间和使用声明,而不是容器中服务的名称。
没有任何其他线索,自动DI可能会寻找与完全合格的类名相匹配的服务,即@var Configuration
。但是,您的服务已注册为Hetwan\Core\Configuration
,因此无法匹配。因此,DI回退到尝试使用Configuration
自动构造实例但是失败,因为构造函数具有必需参数。
我怀疑您需要做的是使用完全限定名称注册您的服务,如下所示:
new \Hetwan\Core\Configuration();
然后,当它去查找$this->containerBuilder->addDefinitions([
'Hetwan\Core\Configuration' => DI\Object('Hetwan\Core\Configuration')
->constructor($this->getRootDir().'/app/config/config.yml')
]);
的实例时,它将找到该服务,而不是尝试运行构造函数。
PHP-DI手册shows how you can simplify this使用the magic constant ::class
来:
\Hetwan\Core\Configuration
或者,您可以告诉PHP-DI注入哪些服务,而不是根据属性类型according to the documentation on annotations进行猜测:
use Hetwan\Core\Configuration;
$this->containerBuilder->addDefinitions([
Configuration::class => DI\Object()
->constructor($this->getRootDir().'/app/config/config.yml')
]);