On this page
Migrate Class Implements FactoryInterface to use Psr Container
To migrate existing factory classes that implements Laminas\ServiceManager\Factory\FactoryInterface
, there is a Rector rule that can be used to migrate for that. For example, we have the following factory class:
use My\Service;
use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
class ServiceFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new Service();
}
}
We need to migrate to :
use My\Service;
use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
class ServiceFactory
{
public function __invoke(\Psr\Container\ContainerInterface $container)
{
return new Service();
}
}
The steps to apply the changes are:
- Remove the interface from Factory class
- Replace
invoke__()
class method param and the use of Interop class in the class
To apply that, we can register rector rule: Laminas\ServiceManager\Migration\Rector\Class_\ImplementsFactoryInterfaceToPsrFactoryRector
to our rector.php
as an individual service:
use Laminas\ServiceManager\Migration\Rector\Set\ValueObject\SetList;
use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->sets([SetList::LAMINAS_SERVICEMANGER_40]);
$rectorConfig->paths([__DIR__ . '/module']);
// register ImplementsFactoryInterfaceToPsrFactoryRector service
$rectorConfig->rule(
\Laminas\ServiceManager\Migration\Rector\Class_\ImplementsFactoryInterfaceToPsrFactoryRector::class
);
};
If we want to auto import, we can use LAMINAS_SERVICEMANGER_40_AUTO_IMPORT
:
use Laminas\ServiceManager\Migration\Rector\Set\ValueObject\SetList;
use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->sets([SetList::LAMINAS_SERVICEMANGER_40_AUTO_IMPORT]);
$rectorConfig->paths([__DIR__ . '/module']);
// register ImplementsFactoryInterfaceToPsrFactoryRector service
$rectorConfig->rule(
\Laminas\ServiceManager\Migration\Rector\Class_\ImplementsFactoryInterfaceToPsrFactoryRector::class
);
};
After configuration in place, we can run:
vendor/bin/rector process --dry-run
Ensure that the change is correct, if everything ok, we can run the fix:
vendor/bin/rector process
Additional Adjustment
Add Return Type to Factory
To add return type by new instance creation, the standard Rector rule ReturnTypeFromReturnNewRector
can be used.
Register the rule in rector.php
:
use Laminas\ServiceManager\Migration\Rector\Class_\ImplementsFactoryInterfaceToPsrFactoryRector;
use Laminas\ServiceManager\Migration\Rector\Set\ValueObject\SetList;
use Rector\Config\RectorConfig;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnNewRector;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->sets([SetList::LAMINAS_SERVICEMANGER_40_AUTO_IMPORT]);
$rectorConfig->paths([__DIR__ . '/module']);
$rectorConfig->rule(ImplementsFactoryInterfaceToPsrFactoryRector::class);
$rectorConfig->rule(ReturnTypeFromReturnNewRector::class);
};
Result:
use My\Service;
use Psr\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
class ServiceFactory
{
public function __invoke(ContainerInterface $container): Service
{
return new Service();
}
}
Sort Use Statements
To sort the use
statements for the factory a coding style tool can be used, for example: PHP_CodeSniffer with Slevomat Coding Standard.