[英]ZF3: ServiceNotFoundException while creating a class with Abstract Factory registered in ServiceManager
使用在ServiceManager中注冊的Abstract Factory創建類時,出現ServiceNotFoundException
。
首先,我使用composer下載zend-servicemanager
composer require zendframework/zend-servicemanager
然后,我在單個文件中運行ServiceManager示例(為簡單起見)。
<?php
require_once 'vendor/autoload.php';
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\Factory\InvokableFactory;
use Zend\ServiceManager\Factory\FactoryInterface;
use Zend\ServiceManager\Factory\AbstractFactoryInterface;
應該通過ServiceManager獲取的類。
class A
{
public $text;
public function __construct()
{
$this->text = "Default text";
}
}
我從文檔中使用MyAbstractFactory。
class MyAbstractFactory implements AbstractFactoryInterface
{
public function canCreate(ContainerInterface $container, $requestedName)
{
return in_array('Traversable', class_implements($requestedName), true);
}
public function __invoke(ContainerInterface $container,
$requestedName,
array $options = null)
{
return $requestedName();
}
}
我用注冊的抽象工廠創建ServiceManager。
$serviceManager = new ServiceManager([
// Neither works
//'abstract_factories' => array('MyAbstractFactory')
'abstract_factories' => array( new MyAbstractFactory() )
//'abstract_factories' => array( MyAbstractFactory::class )
/*
'abstract_factories' => [
MyAbstractFactory::class => new MyAbstractFactory()
]
*/
]);
最后,我嘗試獲取類A的實例。
$a = $serviceManager->get(A::class);
var_dump($a);
我收到Fatal error: Uncaught Zend\\ServiceManager\\Exception\\ServiceNotFoundException: Unable to resolve service "A" to a factory; are you certain you provided it during configuration?
Fatal error: Uncaught Zend\\ServiceManager\\Exception\\ServiceNotFoundException: Unable to resolve service "A" to a factory; are you certain you provided it during configuration?
與堆棧跟蹤
.\vendor\zendframework\zend-servicemanager\src\ServiceManager.php(763): Zend\ServiceManager\ServiceManager->getFactory('A') #1
.\vendor\zendframework\zend-servicemanager\src\ServiceManager.php(200): Zend\ServiceManager\ServiceManager->doCreate('A') #2
.\script.php(53): Zend\ServiceManager\ServiceManager->get('A') #3
我對這個問題的表述是錯誤的。 @rkeet的評論很清楚。
由於我的目標是在ServiceManager中進行抽象工廠注冊的工作示例,因此我發布了單文件腳本,其中canCreate()
得以簡化,只是為了檢查該類是否存在。
<?php
// composer require zendframework/zend-servicemanager
require_once 'vendor/autoload.php';
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\Factory\AbstractFactoryInterface;
class A
{
public $text;
public function __construct()
{
$this->text = "Default text";
}
}
class MyAbstractFactory implements AbstractFactoryInterface
{
public function canCreate(ContainerInterface $container, $requestedName)
{
return class_exists($requestedName);
}
public function __invoke(ContainerInterface $container,
$requestedName,
array $options = null)
{
return new $requestedName();
}
}
$serviceManager = new ServiceManager([
//'abstract_factories' => array('MyAbstractFactory') // works
//'abstract_factories' => array( new MyAbstractFactory() ) // works
'abstract_factories' => array( MyAbstractFactory::class ) // also works
]);
try {
$a = $serviceManager->get(A::class);
var_dump($a);
echo "<br/>\n";
$b = $serviceManager->get(B::class);
var_dump($b);
} catch (Exception $e) {
echo $e->getMessage() . "<br/>\n";
echo "{$e->getFile()} ({$e->getLine()})";
}
?>
正如@rkeet所指出的,如果有人需要原始示例工作,則A
類應實現Traversable 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.