Recently started learning AngularJS and Zend Framework 2 through a course. Given the year of the course, which if I remember is 2013, some things have changed in both frameworks. Soon, I came across a problem using the following code snippet to test the connection to the database and list the records using Doctrine 2:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class IndexController extends AbstractActionController {
public function indexAction() {
$em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
$repo = $em->getRepository('Entity\Categoria');
$categorias = $repo->findAll();
return new ViewModel(['categories'=>$categorias]);
}
}
When I run, it returns the following error::
A plugin by the name "getServiceLocator" was not found in the plugin manager Zend\Mvc\Controller\PluginManager
Furthermore, an additional information:
Zend\ServiceManager\Exception\ServiceNotFoundException
File:
C:\xampp\htdocs\Curso de ZF2\vendor\zendframework\zend-servicemanager\src\AbstractPluginManager.php:133
As far as I know, the problem stems from the fact that the getServiceLocator()
had been removed from the latest version of Zend Framework 2. However, I have no idea how to solve this so that I can continue testing . Someone can help me?
If you have updated or checked out Zend Framework 3 from composer, and if it's just for making your course material work, you could downgrade to an earlier (2.x) version, where
getServiceLocator()
is available, yet deprecated. It was removed from 3.0 onwards.A better approach would be to understand how to work around it, since you will have to do it in the future, anyway. Basically, you shouldn't inject dependencies in the middle of runtime, but actually register a factory for your controller and then pass dependencies in through a constructor. Possible fixes are explained well in the accepted answer for the following question:
PHP Deprecated: You are retrieving the service locator from within the class ZFTool\Controller\ModuleController
In the example above,
$db = $this->getServiceLocator()->get('Db\ApplicationAdapter');
is passed as a constructor argument, so it will be immediately available to the Controller. So in a similar fashion, you should create a Factory for yourIndexController
, which should return it withDoctrine\ORM\EntityManager
already injected through a constructor (remember to replace "yourModule" with your real module name):You could place your Factory class anywhere, as long as everything is configured accordingly. In this example, I've put it in
/Module/yourModule/src/yourModule/Controller/Factory/IndexControllerFactory.php
.With the class above being called, your
$em
variable would then be populated and could be called from anywhere in the controller (note the new property$em
and its usage:$this->em
):Now, register you new factory in yourModule's
module.config.php
and we're done:Very important: your file will probably have similar contents, but using "invokes" as array key. Notice that you will use factories as key name (because you are declaring a controller factory), instead of "invokes", which is for classes without dependencies or regular controllers.
I also recommend studying this Migration guide for Zend Framework 3, it has a lot of important information that might help.
As for that course you are following, again, I suggest you downgrade PHP to a compatible version (very easy if you're using composer), or try to find another up-to-date course or tutorial on the web. ZF2 changed significantly between versions and chances are this is not the only error you will find and you'll get very confused instead of learning. Let me know if this works for you.