Extbase:存储库中的 PersistanceManager 为 NULL
Extbase: PersistanceManager in Repository is NULL
我正在为 TYPO3 8 构建一个扩展,也许我不太了解注入机制,但这是我的情况:
我写了一个服务 class 来查询 API。
所述服务还从本地存储库获取一些信息:
class ApiService {
protected $myRepository
public function __construct() {
$objectManager = GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
$this->myRepository = GeneralUtility::makeInstance(MyRepository::class, $objectManager);
var_dump($this->myRepository->persistanceManager); # outputs NULL
}
public function callerFunction() {
var_dump($this->myRepository->persistenceManager); # outputs NULL
myRepository->someRepositoryFunction();
}
}
这会调用 myRepository->someRepositoryFunction()
:
class MyRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
public function someRepositoryFunction() {
var_dump($this->persistenceManager); # outputs a valid singleton PersistenceManager
$data = $this->findAll(); # succeeds
}
}
此代码在前端控制器中使用时有效。
class MyController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
/**
* @var MyRepository
* @inject
*/
protected $myRepository = null;
public function listAction() {
myRepository->someRepositoryFunction();
}
}
第一个 var_dump
以某种方式输出 NULL
,而第二个 var_dump
神奇地输出了一个有效的单例。
print_r
-Repository::__construct()
和 Repository::injectPersistenceManager()
中的语句似乎没有被调用。因此,我突然无法解释 PersistenceManager 的来源。
简化的堆栈跟踪:
#0 MyExtension\Domain\Repository\MyRepository->someRepositoryFunction() called at [myExtension/Classes/Service/ApiService.php]
#1 MyExtension\Service\ApiService->callerFunction() called at [myExtension/Classes/Domain/Repository/AnotherRepository.php]
#2 MyExtension\Domain\Repository\AnotherRepository->someOtherRepositoryFunction() called at [myExtension/Classes/Controller/MyController.php]
#3 MyExtension\Controller\MyController->listAction()
因为代码有效,所以这不是什么大问题。
但是,如果我从 Task class 调用相同的代码,PersistenceManager stays NULL
.
class MyTask extends AbstractTask
{
protected $apiService = null;
public function execute()
{
$this->apiService = GeneralUtility::makeInstance(ApiService::class);
$data = $this->apiService->callerFunction();
return true;
}
}
再次简化 Stacktrace:
#0 MyExtension\Domain\Repository\MyRepository->someRepositoryFunction() called at [myExtension/Classes/Service/ApiService.php]
#1 MyExtension\Service\ApiService->callerFunction() called at [myExtension/Classes/Task/MyTask.php]
#2 MyExtension\Task\MyTask->execute() called at [typo3/sysext/scheduler/Classes/Scheduler.php]
#3 TYPO3\CMS\Scheduler\Scheduler->executeTask() called at [typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php]
现在抛出 Call to a member function createQueryForType() on null
因为 MyRepository 的 PersistenceManager 是 NULL
.
请注意,在这两种情况下,MyRepository 都是由 ApiService 实例化的!
那么如果我从控制器或任务中调用它有什么区别呢?
ApiService::__construct
在这两种情况下都会被调用。 (尽管 MyRepository
的实例此时仍为 NULL。)
为什么突然出现PersistenceManager?
而不是:
$objectManager = GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
$this->myRepository = GeneralUtility::makeInstance(MyRepository::class, $objectManager);
试试这个:
$objectManager = GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
$this->myRepository = $objectManager->get(MyRepository::class);
objectManager 解决了所有的依赖注入。
我正在为 TYPO3 8 构建一个扩展,也许我不太了解注入机制,但这是我的情况:
我写了一个服务 class 来查询 API。
所述服务还从本地存储库获取一些信息:
class ApiService {
protected $myRepository
public function __construct() {
$objectManager = GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
$this->myRepository = GeneralUtility::makeInstance(MyRepository::class, $objectManager);
var_dump($this->myRepository->persistanceManager); # outputs NULL
}
public function callerFunction() {
var_dump($this->myRepository->persistenceManager); # outputs NULL
myRepository->someRepositoryFunction();
}
}
这会调用 myRepository->someRepositoryFunction()
:
class MyRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
public function someRepositoryFunction() {
var_dump($this->persistenceManager); # outputs a valid singleton PersistenceManager
$data = $this->findAll(); # succeeds
}
}
此代码在前端控制器中使用时有效。
class MyController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
/**
* @var MyRepository
* @inject
*/
protected $myRepository = null;
public function listAction() {
myRepository->someRepositoryFunction();
}
}
第一个 var_dump
以某种方式输出 NULL
,而第二个 var_dump
神奇地输出了一个有效的单例。
print_r
-Repository::__construct()
和 Repository::injectPersistenceManager()
中的语句似乎没有被调用。因此,我突然无法解释 PersistenceManager 的来源。
简化的堆栈跟踪:
#0 MyExtension\Domain\Repository\MyRepository->someRepositoryFunction() called at [myExtension/Classes/Service/ApiService.php]
#1 MyExtension\Service\ApiService->callerFunction() called at [myExtension/Classes/Domain/Repository/AnotherRepository.php]
#2 MyExtension\Domain\Repository\AnotherRepository->someOtherRepositoryFunction() called at [myExtension/Classes/Controller/MyController.php]
#3 MyExtension\Controller\MyController->listAction()
因为代码有效,所以这不是什么大问题。
但是,如果我从 Task class 调用相同的代码,PersistenceManager stays NULL
.
class MyTask extends AbstractTask
{
protected $apiService = null;
public function execute()
{
$this->apiService = GeneralUtility::makeInstance(ApiService::class);
$data = $this->apiService->callerFunction();
return true;
}
}
再次简化 Stacktrace:
#0 MyExtension\Domain\Repository\MyRepository->someRepositoryFunction() called at [myExtension/Classes/Service/ApiService.php]
#1 MyExtension\Service\ApiService->callerFunction() called at [myExtension/Classes/Task/MyTask.php]
#2 MyExtension\Task\MyTask->execute() called at [typo3/sysext/scheduler/Classes/Scheduler.php]
#3 TYPO3\CMS\Scheduler\Scheduler->executeTask() called at [typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php]
现在抛出 Call to a member function createQueryForType() on null
因为 MyRepository 的 PersistenceManager 是 NULL
.
请注意,在这两种情况下,MyRepository 都是由 ApiService 实例化的!
那么如果我从控制器或任务中调用它有什么区别呢?
ApiService::__construct
在这两种情况下都会被调用。 (尽管 MyRepository
的实例此时仍为 NULL。)
为什么突然出现PersistenceManager?
而不是:
$objectManager = GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
$this->myRepository = GeneralUtility::makeInstance(MyRepository::class, $objectManager);
试试这个:
$objectManager = GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
$this->myRepository = $objectManager->get(MyRepository::class);
objectManager 解决了所有的依赖注入。