函数“LoginFormAuthenticator::__construct()”的参数太少,0 正好通过了 4 预期

Posted

技术标签:

【中文标题】函数“LoginFormAuthenticator::__construct()”的参数太少,0 正好通过了 4 预期【英文标题】:Too few arguments to function `LoginFormAuthenticator::__construct()`, 0 passed exactly 4 expected 【发布时间】:2021-02-16 01:24:25 【问题描述】:

需要连接多个数据库,并按照Symfony 文档处理此事。

我创建了多个学说连接和 orm 实体管理器,并禁用了自动装配。

# config/packages/doctrine.yaml
doctrine:
  dbal:
    default_connection: default
    connections:
      default:
        # configure these for your database server
        url: "%env(resolve:DATABASE_URL)%"
        driver: "pdo_mysql"
        server_version: "5.7"
        charset: utf8mb4
      lc_cvo:
        # configure these for your database server
        url: "%env(resolve:DATABASE_LC_CVO_URL)%"
        driver: "pdo_mysql"
        server_version: "5.7"
        charset: utf8mb4
      lc_cvt:
        # configure these for your database server
        url: "%env(resolve:DATABASE_LC_CVT_URL)%"
        driver: "pdo_mysql"
        server_version: "5.7"
        charset: utf8mb4
      lc_ewi:
        # configure these for your database server
        url: "%env(resolve:DATABASE_LC_EWI_URL)%"
        driver: "pdo_mysql"
        server_version: "5.7"
        charset: utf8mb4
      lc_tbo:
        # configure these for your database server
        url: "%env(resolve:DATABASE_LC_TBO_URL)%"
        driver: "pdo_mysql"
        server_version: "5.7"
        charset: utf8mb4
      lc_users:
        # configure these for your database server
        url: "%env(resolve:DATABASE_LC_USERS_URL)%"
        driver: "pdo_mysql"
        server_version: "5.7"
        charset: utf8mb4

orm:
    entity_managers:
      default:
        connection: default
        mappings:
          Main:
            is_bundle: false
            type: annotation
            dir: "%kernel.project_dir%/src/Entity/lmc_lemoncake"
            prefix: 'App\Entity\lmc_lemoncake'
            alias: Main
      lc_cvo:
        connection: lc_cvo
        mappings:
          lc_cvo:
            is_bundle: false
            type: annotation
            dir: "%kernel.project_dir%/src/Entity/lmc_lemoncake-cvo"
            prefix: 'App\Entity\lmc_lemoncake_cvo'
            alias: lc_cvo
      lc_cvt:
        connection: lc_cvt
        mappings:
          lc_cvt:
            is_bundle: false
            type: annotation
            dir: "%kernel.project_dir%/src/Entity/lmc_lemoncake-cvt"
            prefix: 'App\Entity\lmc_lemoncake_cvt'
            alias: lc_cvt
      lc_ewi:
        connection: lc_ewi
        mappings:
          lc_ewi:
            is_bundle: false
            type: annotation
            dir: "%kernel.project_dir%/src/Entity/lmc_lemoncake-ewi"
            prefix: 'App\Entity\lmc_lemoncake_ewi'
            alias: lc_ewi
      lc_tbo:
        connection: lc_tbo
        mappings:
          lc_tbo:
            is_bundle: false
            type: annotation
            dir: "%kernel.project_dir%/src/Entity/lmc_lemoncake-tbo"
            prefix: 'App\Entity\lmc_lemoncake_tbo'
            alias: lc_tbo
      lc_users:
        connection: lc_users
        mappings:
          lc_users:
            is_bundle: false
            type: annotation
            dir: "%kernel.project_dir%/src/Entity/lmc_users"
            prefix: 'App\Entity\lmc_users'
            alias: lc_users

我的 services.yaml 文件如下所示

# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:

services:
  # default configuration for services in *this* file
  _defaults:
    autowire: false # Automatically injects dependencies in your services.
    autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

  # makes classes in src/ available to be used as services
  # this creates a service per class whose id is the fully-qualified class name
  App\:
    resource: "../src/"
    exclude:
      - "../src/DependencyInjection/"
      - "../src/Entity/"
      - "../src/Kernel.php"
      - "../src/Tests/"

  # controllers are imported separately to make sure services can be injected
  # as action arguments even if you don't extend any base controller class
  App\Controller\:
    resource: "../src/Controller/"
    tags: ["controller.service_arguments"]

  # add more service definitions when explicit configuration is needed
  # please note that last definitions always *replace* previous ones

不幸的是,我在尝试访问登录页面时收到以下错误。

Too few arguments to function App\Security\LoginFormAuthenticator::__construct(), 0 passed in /var/www/html/app/var/cache/dev/Container12fc4el/getSecurity_Firewall_Map_Context_MainService.php on line 53 and exactly 4 expected

这里列出了它所指的LoginFormAuthenticator,需要连接到用户信息(用户名,密码)所在的lc_users连接。 我将需要其他连接来获取客户端数据。

class LoginFormAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface

    use TargetPathTrait;

    public const LOGIN_ROUTE = 'app_login';

    private $entityManager;
    private $urlGenerator;
    private $csrfTokenManager;
    private $passwordEncoder;

    public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
    
        $this->entityManager = $entityManager;
        $this->urlGenerator = $urlGenerator;
        $this->csrfTokenManager = $csrfTokenManager;
        $this->passwordEncoder = $passwordEncoder;
    

我认为我需要在我的服务中添加一些内容,以便 Authenticator 检索正确的连接,不幸的是我对此事的了解不够。

我需要为多个客户端使用多个数据库。

如何解决手头的问题? 如何防止其他连接出现此问题? 我是否以正确的方式处理此问题,还是有更好的方法来连接到多个数据库?

提前感谢您的帮助,请随时询问更多信息。

编辑: 感谢@msg 的回答;我已经设法通过以下代码使其工作:

app/config/services.yaml:

App\Security\LoginFormAuthenticator:
    autowire: true
    tags: ["doctrine.repository_service"]
    arguments:
      $entityManager: "@doctrine.orm.lc_users_entity_manager"

app/config/doctrine.yaml:

  orm:
    default_entity_manager: default
    entity_managers:
      auto_generate_proxy_classes: "%kernel.debug%"
      auto_mapping: true
      default:
         ...

      lc_users:
        connection: lc_users
        mappings:
          App\Entity\lmc_lemoncake:
            is_bundle: false
            type: annotation
            dir: "%kernel.project_dir%/src/Entity/lmc_users"
            prefix: 'App\Entity\lmc_users'
            alias: lc_users

(部分)LoginFormAuthenticator 的 getUser 函数:

$em = $this->entityManager;
$repo = $em->getRepository(Users::class, 'lc_users');
$user = $repo->findOneBy(['username' => $credentials['username']]);

【问题讨论】:

尝试更改autowire: true 如前所述,您需要将 autowire 设置为 true 以进行自动注入。但是,容器无法知道要注入哪个实体管理器。因此,您需要更进一步,绑定您的实体管理器变量或手动定义您的 LoginFormAuthenticator。我担心您将不得不花一些时间阅读有关服务的文档。 注入EntityManager 会让你得到默认的。如果您需要访问类中的多个连接,您可以注入 ManagerRegistry 并检索您需要的服务,但请记住,它可能会带来一系列问题。 将 autowire 设置为 true 然后调用错误的数据库。我会花一些时间阅读@Cerad 所说的服务,然后在找到答案后将答案放在这里。 尝试从不同的资源中学习,但它们让我一点也不聪明。如果有人可以发布一个我可以学习的示例,将不胜感激。每当我尝试来自不同来源的解决方案时,都会被引导到一条不同的错误路径上。 【参考方案1】:

如前所述,注入EntityManager 将获得default 之一。 Doctrine 将为每个经理注册一个名为 doctrine.orm.%manager_name%_entity_manager 的服务。

因此,如果您需要不同的,您有多种选择:

1.显式配置您的服务以使用您需要的管理器:

services:
    App\Security\LoginFormAuthenticator: 
        arguments:
            # Override the Manager, other arguments will be autowired.
            $entityManager: '@doctrine.orm.lc_users_entity_manager'

2.为不同的实体管理者创建不同的bindings:

_defauts:
    bind:
        $cvoManager: '@doctrine.orm.lc_cvo_entity_manager'
        $usersManager: '@doctrine.orm.lc_users_entity_manager'
        # Other managers...

根据你依赖的变量名,将注入适当的管理器:

public function __construct(
    EntityManagerInterface $entityManager, // Default manager
    EntityManagerInterface $usersManager,
)

3.如果你有很多依赖,你也可以注入ManagerRegistry(当你调用getDoctrine()时你在AbstractController中得到的对象)。它充当服务定位器,您可以在其中retrieve managers or repositories:

    use Doctrine\Persistence\ManagerRegistry;

    public function __construct(ManagerRegistry $registry) 
        $userManager = $registry->getManager('users');
    

如果您有许多具有不同依赖项的服务,第一个选项可能会很快变得笨拙,如果您需要模拟注册表,第三个选项将掩盖您的真实依赖项并使测试复杂化。

【讨论】:

非常感谢@msg,我已经成功登录,使用您提供的第一种方法。

以上是关于函数“LoginFormAuthenticator::__construct()”的参数太少,0 正好通过了 4 预期的主要内容,如果未能解决你的问题,请参考以下文章

Symfony 3.4 自动装配服务

损失函数(损失函数代价函数目标函数)​​​​​​​MSE0-1损失函数绝对误差损失函数分位数损失函数Huber损失函数感知损失函数Hinge损失函数指数损失函数对数损失函数

Kotlin函数 ⑧ ( 函数引用 作为函数参数 | ::函数名 | 函数类型 作为函数返回值类型 )

测开之函数进阶篇・第五篇《递归函数纯函数匿名函数偏函数》

8InfluxDB常用函数聚合函数,count()函数,DISTINCT()函数,MEAN()函数,MEDIAN()函数,SPREAD()函数,SUM()函数

Kotlin函数式编程 ② ( 过滤函数 | predicate 谓词函数 | filter 过滤函数 | 合并函数 | zip 函数 | folder 函数 | 函数式编程意义 )