TYPO3 v10.4.21 自定义FormFinisher:同时执行导致异常
TYPO3 v10.4.21 custom FormFinisher: Simultaneous execution resulting in exception
我们使用以下构造函数创建了自定义表单完成器:
/**
* @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager $persistenceManager
*/
protected $persistenceManager = null;
/**
* @var \[NAMESPACE]\[ExtName]\Domain\Repository\ArticleRepository $articleRepository
*/
protected $articleRepository = null;
public function __construct() {
parent::__construct();
$this->persistenceManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
$this->articleRepository = GeneralUtility::makeInstance(\[NAMESPACE]\[ExtName]\Domain\Repository\ArticleRepository::class);
}
当几乎同时执行表单时(测试延迟 1-5 秒),其中一位表单提交者收到错误:
Too few arguments to function
TYPO3\CMS\Extbase\Persistence\Repository::__construct(), 0 passed in
[path_to_docroot]/httpdocs/typo3/sysext/core/Classes/Utility/GeneralUtility.php
on line 3477 and exactly 1 expected
当它试图创建 ArticleRepository 的实例时会发生这种情况:
1:
at
TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('[NAMESPACE]\[ExtName]\Domain\Repository\ArticleRepository')
in
[path_to_docroot]/httpdocs/typo3conf/ext/[ext_name]/Classes/Domain/Finishers/ImageGalleryFinisher.php
line 31
28 public function __construct() {
29 parent::__construct();
30 $this->persistenceManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
31 $this->articleRepository = GeneralUtility::makeInstance(\[NAMESPACE]\[ExtName]\Domain\Repository\ArticleRepository::class);
32 }
2:
at TYPO3\CMS\Extbase\Persistence\Repository->__construct() in
[path_to_docroot]/httpdocs/typo3/sysext/core/Classes/Utility/GeneralUtility.php
line 3477
3473 return self::$container->get($className);
3474 }
3475
3476 // Create new instance and call constructor with parameters
3477 $instance = new $finalClassName(...$constructorArguments);
3478 // Register new singleton instance, but only if it is not a known PSR-11 container service
3479 if ($instance instanceof SingletonInterface && !(self::$container !== null && self::$container->has($className))) {
3480 self::$singletonInstances[$finalClassName] = $instance;
3481 }
3(出现错误的地方):
in
[path_to_docroot]/httpdocs/typo3/sysext/extbase/Classes/Persistence/Repository.php
line 71
67 * Constructs a new Repository
68 *
69 * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
70 */
71 public function __construct(ObjectManagerInterface $objectManager)
72 {
73 $this->objectManager = $objectManager;
74 $this->objectType = ClassNamingUtility::translateRepositoryNameToModelName($this->getRepositoryClassName());
75 }
另一个提交执行没有问题。我们已经在暂存环境中对此进行了测试。我的同事无法通过同时执行 2 个表单在本地重现相同的错误(尽管他的执行速度可能比暂存环境更快)。
我发现问题出在整理器的同时执行上。但为什么?这可以预防吗?是否可以将 ObjectManagerInterface
传递给此构造函数?
或者谁能看出另一个缺陷?或者这是核心某处的错误?
我找不到任何东西...非常感谢任何帮助或指点,谢谢。
在尝试了许多不同的事情后,我最终找到了解决方案。
使用注入注释:
/**
* @var PersistenceManager $persistenceManager
* @\TYPO3\CMS\Extbase\Annotation\Inject
*/
protected $persistenceManager = null;
/**
* @var ArticleRepository $articleRepository
* @\TYPO3\CMS\Extbase\Annotation\Inject
*/
protected $articleRepository = null;
然后可以删除构造函数,它可以同时执行。干杯!
我们使用以下构造函数创建了自定义表单完成器:
/**
* @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager $persistenceManager
*/
protected $persistenceManager = null;
/**
* @var \[NAMESPACE]\[ExtName]\Domain\Repository\ArticleRepository $articleRepository
*/
protected $articleRepository = null;
public function __construct() {
parent::__construct();
$this->persistenceManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
$this->articleRepository = GeneralUtility::makeInstance(\[NAMESPACE]\[ExtName]\Domain\Repository\ArticleRepository::class);
}
当几乎同时执行表单时(测试延迟 1-5 秒),其中一位表单提交者收到错误:
Too few arguments to function TYPO3\CMS\Extbase\Persistence\Repository::__construct(), 0 passed in [path_to_docroot]/httpdocs/typo3/sysext/core/Classes/Utility/GeneralUtility.php on line 3477 and exactly 1 expected
当它试图创建 ArticleRepository 的实例时会发生这种情况:
1:
at TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('[NAMESPACE]\[ExtName]\Domain\Repository\ArticleRepository') in [path_to_docroot]/httpdocs/typo3conf/ext/[ext_name]/Classes/Domain/Finishers/ImageGalleryFinisher.php line 31
28 public function __construct() {
29 parent::__construct();
30 $this->persistenceManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
31 $this->articleRepository = GeneralUtility::makeInstance(\[NAMESPACE]\[ExtName]\Domain\Repository\ArticleRepository::class);
32 }
2:
at TYPO3\CMS\Extbase\Persistence\Repository->__construct() in [path_to_docroot]/httpdocs/typo3/sysext/core/Classes/Utility/GeneralUtility.php line 3477
3473 return self::$container->get($className);
3474 }
3475
3476 // Create new instance and call constructor with parameters
3477 $instance = new $finalClassName(...$constructorArguments);
3478 // Register new singleton instance, but only if it is not a known PSR-11 container service
3479 if ($instance instanceof SingletonInterface && !(self::$container !== null && self::$container->has($className))) {
3480 self::$singletonInstances[$finalClassName] = $instance;
3481 }
3(出现错误的地方):
in [path_to_docroot]/httpdocs/typo3/sysext/extbase/Classes/Persistence/Repository.php line 71
67 * Constructs a new Repository
68 *
69 * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
70 */
71 public function __construct(ObjectManagerInterface $objectManager)
72 {
73 $this->objectManager = $objectManager;
74 $this->objectType = ClassNamingUtility::translateRepositoryNameToModelName($this->getRepositoryClassName());
75 }
另一个提交执行没有问题。我们已经在暂存环境中对此进行了测试。我的同事无法通过同时执行 2 个表单在本地重现相同的错误(尽管他的执行速度可能比暂存环境更快)。
我发现问题出在整理器的同时执行上。但为什么?这可以预防吗?是否可以将 ObjectManagerInterface
传递给此构造函数?
或者谁能看出另一个缺陷?或者这是核心某处的错误?
我找不到任何东西...非常感谢任何帮助或指点,谢谢。
在尝试了许多不同的事情后,我最终找到了解决方案。
使用注入注释:
/**
* @var PersistenceManager $persistenceManager
* @\TYPO3\CMS\Extbase\Annotation\Inject
*/
protected $persistenceManager = null;
/**
* @var ArticleRepository $articleRepository
* @\TYPO3\CMS\Extbase\Annotation\Inject
*/
protected $articleRepository = null;
然后可以删除构造函数,它可以同时执行。干杯!