I'm a beginner about Dependency Injection and I'm using the following tools into my PHP 5.5.9 (under Apache2 and MySql) project:
All my classes use to be autoloaded by composer.
I already got some insight about PHP-DI Definitions by reading it's docs and running it's examples related to autowiring , annotations and config and I've been put it to work with my own classes, but now I'm stuck about how to set vendor libraries such as PHPActiveRecord.
Usually to use PHPActiveRecord all you need is to define connections settings like this:
$cfg = ActiveRecord\Config::instance();
['development' => 'mysql://username:[email protected]/database_name']
Finally your models should extends ActiveRecord\Model and you're ready to go.
For now I'm trying to inject my ActiveRecord models into controllers by using annotations such as PHP-DI's documentation suggests:
* @var User
public function index()
Here I got the error:
Fatal error: Uncaught exception 'ActiveRecord\DatabaseException' with message 'Empty connection string' in /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/Connection.php:105
#0 /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/ConnectionManager.php(33): ActiveRecord\Connection::instance(NULL)
#1 /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/Table.php(117): ActiveRecord\ConnectionManager::get_connection(NULL)
#2 /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/Table.php(93): ActiveRecord\Table->reestablish_connection(false)
#3 /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/Table.php(74): ActiveRecord\Table->__construct('Model\User')
#4 /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/Model.php(749): ActiveRecord\Table::load('Model\User')
#5 /home/ubuntu/workspace/vendor/php-activerecord/php-activerecord/lib/Model.php(262): ActiveRecord\Model::table()
#6 [internal function]: ActiveRecord\Model- in /home/ubuntu/workspace/vendor/mnapoli/php-di/src/DI/Definition/Resolver/ClassDefinitionResolver.php on line 276
As it seems, no string connection provided to ActiveRecord.
I just believe that I need a proper File Configuration setting (DI\factory I think) to return a ActiveRecord\Config instance based on the connection definitions above.
Another point the bring me worries is that PHPActiveRecord have a considerable amount of Singletons and statics functions into it's API and as far as I know it's considered an anti-pattern due to kinda tight coupling issues and it seems no good to DI's management once in this cases there's no well defined "injection points" such as constructor and/or setter injections.
If you think I'm not clear enough about my problem, aske me for and I can provide more info.
I'm afraid there isn't a good solution for your problem. As you have said, PHPActiveRecord is a library built on singletons and static methods, that doesn't mix well with dependency injection.
But mainly, in your example, you are trying to inject a model object. That's (usually) something you should never do. You should inject configuration values or "services" or whatever objects are shared throughout the application, but not models.
Models are fetched from the database depending on queries (for example an ID). So it doesn't make sense to inject a user in the controller since by definition there are many users (there's a whole table of them).
What is usually done is inject the object/service that provides a way to retrieve the models. Those objects are sometimes called "repository" depending on the library. So it goes like this:
Technically, the problem you get here is (I think) PHP-DI trying to create a new User instance (using
new) and PHPActiveRecord trying to connect to the database automatically. Since nothing was configured for the database (I guess), PHPActiveRecord fails.
So in short, what to do?
If you want to dump PHPActiveRecord, maybe have a look at Doctrine (which is more complex) or Propel (which should be closer to what PHPActiveRecord do).