【问题标题】:PHP - Symfony: How do i make a new object inside a class that's from another class?PHP - Symfony:我如何在一个来自另一个类的类中创建一个新对象?
【发布时间】:2017-11-29 09:28:14
【问题描述】:

我制作了一个 PHP Symfony 项目用于学习目的。现在我被卡住了,所以我有一个控制器,它呈现一个视图。但是在那个控制器里面我想访问另一个控制器并创建一个对象,因为我需要它的方法。

简而言之:我如何在 Symfony 的另一个类中创建一个类/对象?

这是我的代码:

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

use AppBundle\Entity\User;
use AppBundle\Controller\LoginController;

class HomeController extends Controller
{

    /**
     * @Route("/", name="home")
     */
    public function renderIndexAction(Request $request)
    {
        $user = new User();

        $form = $this->createFormBuilder($user)
            ->add('username', TextType::class, array('label' => 'username:'))
            ->add('password', PasswordType::class, array('label' => 'password:'))
            ->add('save', SubmitType::class, array('label' => 'login'))
            ->getForm();

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $user = $form->getData();
            $user_username = $user->getUsername();
            $user_password = $user->getPassword();

            $loginController = new LoginController();
            $user = $loginController->checkAction();


            $session = $request->getSession();
            $data = "test";
            $session->set('form_data', $data);


            return $this->redirectToRoute('addressbook');
        }

        return $this->render('home/index.html.twig', array('form' => $form->createView()));
    }
}

所以我想在我的 HomeController 中使用 LoginController。但它给了我一个错误:

在 null 上调用成员函数 has() 500 内部服务器错误 - FatalThrowableError

PS:是的,我知道我的应用程序不安全,但我仍在学习基本的 OOP。所以像这样调用 LoginController 可能是一种奇怪的方式。但这是为了学习目的。

【问题讨论】:

  • 你从那里需要什么方法?在这里添加它的代码。您可能希望将其提取到单独的服务中并注入到两个控制器中,而不是尝试在另一个控制器中创建控制器。
  • 如果你想访问另一个控制器的另一个端点,查找子请求。如果你想重用另一个控制器的方法,把那个方法变成一个服务,并在两个控制器中注入使用那个服务。
  • 你不想在你的控制器中使用另一个控制器的实例,这是错误的逻辑;你应该阅读 MVC 原理。在您的情况下,您可能想要创建另一个类 - 一个服务类,并且两个控制器都将使用该服务。您还应该阅读依赖注入,以加载服务类。
  • 为什么在另一个Controller里面做一个Controller是错的?我想要的只是从另一个类中的一个类创建一个对象?
  • 我正在尝试从该控制器提供服务。写在 services.yml 中是否足够: services: app.login_controller: class: AppBundle\Controller\LoginController 我可以这样调用 LoginController: $loginController = app.login_controller; ?

标签: php symfony oop model-view-controller symfony-2.8


【解决方案1】:

看起来您的问题实际上源于您使用错误的控制器这一事实。您已经在其中管理了 应用程序逻辑,这导致了您当前的问题。

与其创建User 实例并在控制器中进行身份验证,所有这些都应由服务处理(如Authentication 服务)。如果控制器需要访问服务,则应将所述服务作为依赖项传递给该控制器。

这也为您提供了一种在多个控制器之间共享逻辑的自然方式,因为多个控制器可以依赖相同的服务。

更新

所以,services.yml 文件看起来有点像这样:

services:

    controller.auth:
        class: 'Application\Controller\Authentication'
        arguments: ['@service.recognition', '@service.comunity']

    controller.account:
        class: 'Application\Controller\Authentication'
        arguments: ['@service.comunity']

    service.recognition:
        class: 'Model\Service\Recognition'

    service.community:
        class: 'Model\Service\Community'

在这种情况下,Community 服务在两个不相关的控制器之间共享。

附注你可能会发现this post很有用

【讨论】:

  • 为什么在另一个Controller里面做一个Controller是错的?我想要的只是从另一个类中的一个类创建一个对象?
  • 我正在尝试从该控制器提供服务。写在 services.yml 中是否足够: services: app.login_controller: class: AppBundle\Controller\LoginController 我可以这样调用 LoginController: $loginController = app.login_controller; ?
  • NVM,它现在可以工作了。我现在正在使用一项服务。这个链接解释它:symfony.com/doc/2.8/service_container.html
  • @alandibat 更新以显示示例。请不要从控制器类中调用 DI 容器。
  • @alandibat 至于“为什么这是个坏主意”,有几个原因。首先,它会导致控制器(它应该是应用程序中最轻量级的部分)之间的紧密耦合。这也意味着,您的控制器现在有额外的责任 - “在单独的上下文中重新执行”。 Aaaand,您最终还会得到一些没有一致方法的“控制器”(例如,在 Sf2.x 中,您通常会从所有公共方法返回一个 Response 实例)。
【解决方案2】:

您可以从另一个控制器使用控制器的唯一方法是将控制器定义为服务,然后使用它。

看看这个答案how-to-access-a-different-controller-from-inside-a-controller-symfony2

这里是官方文档Define Controllers as Services

【讨论】:

  • 如果你需要从另一个控制器调用一个控制器,那么你就犯了一个架构错误。
  • @tereško 我同意,如果您检测到请求应该由另一个控制器处理,那么为了准确起见,在这种情况下,您可能会将请求转发给另一个控制器。这是一个特定的案例,不用担心,只要知道它存在就可以了
  • 为什么在另一个Controller里面做一个Controller是错的?我想要的只是从另一个类中的一个类创建一个对象?
  • 我正在尝试从该控制器提供服务。写在 services.yml 中是否足够: services: app.login_controller: class: AppBundle\Controller\LoginController 我可以这样调用 LoginController: $loginController = app.login_controller; ?
  • NVM,它现在可以工作了。我现在正在使用一项服务。这个链接解释它:symfony.com/doc/2.8/service_container.html
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-23
  • 1970-01-01
相关资源
最近更新 更多