I have a Controller that extends AbstractActionController'
. This line of code generates a deprecated message:
$config = $this->getServiceLocator()->get('Config');
But this line of code does not:
$config = $this->servicelocator->get('Config');
Question: Is this second version still following an anti-pattern?
More important Question: when ServiceLocatorAwareInterface
is removed, will that 2nd version continue to work?
Same name, same result, same anti-pattern.
No because the whole concept is an anti-pattern.
See also in the migration guide of laminas-mvc.
But this does not mean that you have to write more factories now.
laminas-servicemanager and laminas-mvc can help here with some factories and autowiring:
Another option is to create configuration maps: Configuration-based Abstract Factory - laminas-servicemanager - Laminas Docs
For your example with the config
this means:
class ExampleController extends Laminas\Mvc\Controller\AbstractActionController
{
private array $config;
public function __construct(array $config)
{
$this->config = $config;
}
public function indexAction()
{
$something = $this->config['something'];
}
}
use Laminas\Mvc\Controller\LazyControllerAbstractFactory;
return [
'controllers' => [
'factories' => [
MyModule\Controller\ExampleController::class => LazyControllerAbstractFactory::class,
],
],
// …
];
- A parameter named
$config
typehinted as an array will receive the application “config” service (i.e., the merged configuration).
1 Like
yea… I suspected that was the answer that I’d get.
The LazyControllerAbstractFactory
sounds great but unavailable to me right now because the app is still a Zend Framework 2 .4 app under php 5.6. Our plan is to:
- Get rid of ServiceLocater anti-pattern,
- Refactor code that would be problematic under php 7.4
- Switch to php 7.4 (still a ZF2 app)
- Start using Composer for autoloading
- Convert it to Laminas-MVC.
(This was our first php app - written by coders new to php 4 years ago.)
We are still on step #1; unfortunately, there are MANY instances where we use Service Manager (ugh!)
Thank you, @froschdesign , you have been very helpful to many people in this forum (including me!). It is obvious that you know this framework very well.
Question: Do you think that we are proceeding in the correct sequence (steps 1-5 above)?
I wonder if it might be better to get rid of ServiceLocator after it is running under php 7.4 and converted to Laminas-MVC (obviously, we’d have to filter out the user_deprecated messages).
I think this could also work as a first step.
Can be done before.
Try to jump to version 2.7 of zend-mvc / zendframework, this works with PHP 5.6. Then you can use constructor injection for your controllers with the help of Zend\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory
. The usage is the same as in laminas-servicemanager:
namespace MyModule\Controller;
use Zend\Form\FormElementManager;
class ExampleController extends Zend\Mvc\Controller\AbstractActionController
{
/** @var FormElementManager */
private $formElementManager;
public function __construct(FormElementManager $formElementManager)
{
$this->formElementManager = $formElementManager;
}
public function indexAction()
{
$form = $this->formElementManager->get(ExampleForm::class);
}
}
use Zend\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory;
return [
'controllers' => [
'factories' => [
MyModule\Controller\ExampleController::class => ReflectionBasedAbstractFactory::class,
],
],
// …
];