Symfony FOSUserBundle 用户管理器扩展
Symfony FOSUserBundle user manager extension
我正在开发一个由 Symfony 3 提供支持的 RESTful 应用程序,使用 FOSRestBundle、FOSUserBundle 和 FOSOAuthBundle。
我的问题是我想扩展 FOS UserManager class,但这会引发致命错误:
Type error: Argument 1 passed to FOS\UserBundle\Doctrine\UserManager::__construct() must implement interface FOS\UserBundle\Util\PasswordUpdaterInterface, none given, called in /var/www/html/var/cache/dev/appDevDebugProjectContainer.php on line 2538
以下是我的部分申请文件:
# app/config/config.yml
fos_user:
# [...]
service:
user_manager: foo.user_manager
# src/FooBundle/Resources/config/services.yml
services:
# [...]
foo.user_manager:
class: FooBundle\Service\UserManager
FooBundle\Service\UserManager:
arguments:
$class: '%fos_user.model.user.class%'
<?php
// src/FooBundle/Service/UserManager.php
namespace FooBundle\Service;
use FOS\UserBundle\Doctrine\UserManager as BaseUserManager;
class UserManager extends BaseUserManager implements UserManagerInterface
{
/**
* {@inheritDoc}
* @see \FooBundle\Service\UserManagerInterface::findUsersAtPage()
*/
public function findUsersAtPage($usersPerPage, $page) {
$offset = $usersPerPage * $page;
return $this->getRepository()->findBy(array(), null, $usersPerPage, $offset);
}
}
<?php
// src/FooBundle/Service/UserManagerInterface.php
namespace FooBundle\Service;
use FOS\UserBundle\Model\UserManagerInterface as BaseUserManagerInterface;
interface UserManagerInterface extends BaseUserManagerInterface
{
/**
* Returns a collection with specified number of user instances at specified page.
* @param int $usersPerPage The number of users per page.
* @param int $page The page number.
* @return \Traversable
*/
public function findUsersAtPage($usersPerPage, $page);
}
我观察到的是,当我使用默认的 FOS 用户管理器时,appDevDebugProjectContainer.php 生成 getter 方法(带参数):
<?php
// var/cache/dev/appDevDebugProjectContainer.php
class appDevDebugProjectContainer extends Container
{
// [...]
protected function getFosUser_UserManagerService()
{
return $this->services['fos_user.user_manager'] = new \FOS\UserBundle\Doctrine\UserManager(${($_ = isset($this->services['fos_user.util.password_updater']) ? $this->services['fos_user.util.password_updater'] : $this->getFosUser_Util_PasswordUpdaterService()) && false ?: '_'}, ${($_ = isset($this->services['fos_user.util.canonical_fields_updater']) ? $this->services['fos_user.util.canonical_fields_updater'] : $this->getFosUser_Util_CanonicalFieldsUpdaterService()) && false ?: '_'}, ${($_ = isset($this->services['fos_user.object_manager']) ? $this->services['fos_user.object_manager'] : $this->getFosUser_ObjectManagerService()) && false ?: '_'}, 'FooBundle\Entity\User');
}
// [...]
}
当我使用我的(不带参数)时:
<?php
// var/cache/dev/appDevDebugProjectContainer.php
class appDevDebugProjectContainer extends Container
{
// [...]
protected function getFosUser_UserManagerService()
{
return $this->services['fos_user.user_manager'] = new \FooBundle\Service\UserManager();
}
// [...]
}
拜托,有人可以帮助我吗?
好的,这就是答案:
必须在服务定义中设置服务参数,而不是 class 服务定义。这不是很清楚,所以比文字更好,一些代码:
# src/FooBundle/Resources/config/services.yml
services:
# [...]
foo.user_manager:
class: FooBundle\Service\UserManager
arguments:
$class: '%fos_user.model.user.class%'
FooBundle\Service\UserManager: '@foo.user_manager'
我以为我试过了,但我没有...
刚刚解决了类似的问题。也许会对某人有所帮助。 Check this answer
或者试试这个
services:
you_bundle.user_manager:
class: YourBundle\Services\UserManager
arguments: ["@fos_user.util.password_updater", "@fos_user.util.canonical_fields_updater", "@doctrine.orm.entity_manager", "%fos_user.model.user.class%"]
我正在开发一个由 Symfony 3 提供支持的 RESTful 应用程序,使用 FOSRestBundle、FOSUserBundle 和 FOSOAuthBundle。
我的问题是我想扩展 FOS UserManager class,但这会引发致命错误:
Type error: Argument 1 passed to FOS\UserBundle\Doctrine\UserManager::__construct() must implement interface FOS\UserBundle\Util\PasswordUpdaterInterface, none given, called in /var/www/html/var/cache/dev/appDevDebugProjectContainer.php on line 2538
以下是我的部分申请文件:
# app/config/config.yml
fos_user:
# [...]
service:
user_manager: foo.user_manager
# src/FooBundle/Resources/config/services.yml
services:
# [...]
foo.user_manager:
class: FooBundle\Service\UserManager
FooBundle\Service\UserManager:
arguments:
$class: '%fos_user.model.user.class%'
<?php
// src/FooBundle/Service/UserManager.php
namespace FooBundle\Service;
use FOS\UserBundle\Doctrine\UserManager as BaseUserManager;
class UserManager extends BaseUserManager implements UserManagerInterface
{
/**
* {@inheritDoc}
* @see \FooBundle\Service\UserManagerInterface::findUsersAtPage()
*/
public function findUsersAtPage($usersPerPage, $page) {
$offset = $usersPerPage * $page;
return $this->getRepository()->findBy(array(), null, $usersPerPage, $offset);
}
}
<?php
// src/FooBundle/Service/UserManagerInterface.php
namespace FooBundle\Service;
use FOS\UserBundle\Model\UserManagerInterface as BaseUserManagerInterface;
interface UserManagerInterface extends BaseUserManagerInterface
{
/**
* Returns a collection with specified number of user instances at specified page.
* @param int $usersPerPage The number of users per page.
* @param int $page The page number.
* @return \Traversable
*/
public function findUsersAtPage($usersPerPage, $page);
}
我观察到的是,当我使用默认的 FOS 用户管理器时,appDevDebugProjectContainer.php 生成 getter 方法(带参数):
<?php
// var/cache/dev/appDevDebugProjectContainer.php
class appDevDebugProjectContainer extends Container
{
// [...]
protected function getFosUser_UserManagerService()
{
return $this->services['fos_user.user_manager'] = new \FOS\UserBundle\Doctrine\UserManager(${($_ = isset($this->services['fos_user.util.password_updater']) ? $this->services['fos_user.util.password_updater'] : $this->getFosUser_Util_PasswordUpdaterService()) && false ?: '_'}, ${($_ = isset($this->services['fos_user.util.canonical_fields_updater']) ? $this->services['fos_user.util.canonical_fields_updater'] : $this->getFosUser_Util_CanonicalFieldsUpdaterService()) && false ?: '_'}, ${($_ = isset($this->services['fos_user.object_manager']) ? $this->services['fos_user.object_manager'] : $this->getFosUser_ObjectManagerService()) && false ?: '_'}, 'FooBundle\Entity\User');
}
// [...]
}
当我使用我的(不带参数)时:
<?php
// var/cache/dev/appDevDebugProjectContainer.php
class appDevDebugProjectContainer extends Container
{
// [...]
protected function getFosUser_UserManagerService()
{
return $this->services['fos_user.user_manager'] = new \FooBundle\Service\UserManager();
}
// [...]
}
拜托,有人可以帮助我吗?
好的,这就是答案:
必须在服务定义中设置服务参数,而不是 class 服务定义。这不是很清楚,所以比文字更好,一些代码:
# src/FooBundle/Resources/config/services.yml
services:
# [...]
foo.user_manager:
class: FooBundle\Service\UserManager
arguments:
$class: '%fos_user.model.user.class%'
FooBundle\Service\UserManager: '@foo.user_manager'
我以为我试过了,但我没有...
刚刚解决了类似的问题。也许会对某人有所帮助。 Check this answer
或者试试这个
services:
you_bundle.user_manager:
class: YourBundle\Services\UserManager
arguments: ["@fos_user.util.password_updater", "@fos_user.util.canonical_fields_updater", "@doctrine.orm.entity_manager", "%fos_user.model.user.class%"]