I try to make a project with PHP-DI but i have a problem.
This is the trace:
Here is the code:
Container class:
$this->containerBuilder->addDefinitions([
'Configuration' => DI\Object('Hetwan\Core\Configuration')->constructor($this->getRootDir().'/app/config/config.yml'),
'Database' => DI\object('Hetwan\Core\Database')
]);
Configuration class:
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;
}
}
Database class:
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;
}
}
I can acces to $container->get('Configuration')
without any problem and it works.
But at the creation of Database class i think PHP-DI try to recreate an instance of Configuration and i don't know why because an singleton instance is already here.
Thank you for the help!
The annotation
@var Configuration
is likely to be interpreted as a class name, based on the file's namespace and use declarations, not the name of a service in the container.Without any other clues, the automatic DI will presumably look for a service matching that fully-qualified class name, i.e.
Hetwan\Core\Configuration
. However, your service is registered asConfiguration
, so doesn't match. So the DI falls back to trying to construct an instance automatically usingnew \Hetwan\Core\Configuration();
but fails, because the constructor has a required parameter.I suspect what you need to do is register your service with the fully-qualified name, like this:
Then when it goes to look for an instance of
\Hetwan\Core\Configuration
it will find that service, rather than trying to run the constructor.The PHP-DI manual shows how you can simplify this using the magic constant
::class
to:Alternatively, you can tell PHP-DI which service to inject, rather than having it guess based on the type of the property, according to the documentation on annotations: