无法在其他课程中使用教义

雷扎·萨达蒂(Reza Saadati)

我在控制器类中使用以下代码:

$entityManager = $this->getDoctrine()->getManager();

$user = new Users();
$user->setEmail($data['email']);
$user->setActive(false);
$user->setPassword($data['password']);
$user->setRegisterDate(date('Y-m-d H:i:s'));

$entityManager->persist($user);
$entityManager->flush();

效果很好!

我尝试在另一个文件中使用的相同代码。因此,在我的情况下,控制器类接收数据并将其发送到服务类。服务类将验证数据并将其发送到DAO类。看起来像这样:

AuthorizationController.php

<?php
namespace App\Controller;

use App\Service\AuthorizationService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class AuthorizationController extends AbstractController {
    /**
     * @Route("/register/save", methods={"POST", "HEAD"})
     * @param Request $request
     * @return Response
     */
    public function save(Request $request) {
        if ($request->getMethod() === 'POST') {
            $data = json_decode($request->getContent(), true);
            $service = new AuthorizationService();
            $service->register($data);
        }

        return new Response('test');
    }
}

AuthorizationService.php

<?php
namespace App\Service;

use App\Dao\AuthorizationDao;

class AuthorizationService {
    function register($data) {
        $email    = $data['email'] ?? 'e';
        $password = $data['password'] ?? 'p';
        $val_email = false;
        $val_password = false;

        // Email validation
        if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $val_email = true;
        }

        // Password validation
        if (strlen($password) > 5) {
            $val_password = true;
        }

        // Send the response
        if ($val_email && $val_password) {
            $dao = new AuthorizationDao();
            $dao->register($data);
        }
    }
}

AuthorizationDao.php

<?php
namespace App\Dao;

use App\Entity\Users;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class AuthorizationDao extends AbstractController {
    function register($data) {
        $entityManager = $this->getDoctrine()->getManager();

        $user = new Users();
        $user->setEmail($data['email']);
        $user->setActive(false);
        $user->setPassword($data['password']);
        $user->setRegisterDate(date('Y-m-d H:i:s'));

        $entityManager->persist($user);
        $entityManager->flush();
    }
}

如果代码在我的控制器类中,则可以使用Doctrine,但如果要在AuthorizationDao.php中使用它,它将无法正常工作。我将收到以下错误:

在null上调用成员函数has()

我究竟做错了什么?

佳美

恕我直言,对您的实际问题的适当解决方案EntityManagerInterface注入您的AuthorizationService中,然后在那儿使用它。调用控制器的服务是代码异味!(如果您不知道什么是依赖注入,请在symfony的上下文中继续阅读!)

错误的解释:

AbstractController(扩展)是一个ContainerAwareInterface,它将被初始化,然后AbstractController::setContainer($container)调用,当且仅当它通过symfony的依赖项注入(如果需要,加上附加的自动装配)注入。

AbstractController::getDoctrine() 使用容器获得教义服务。

但是,由于在调用时不使用依赖项注入

$dao = new AuthorizationDao();

AuthorizationDao没有容器,无法获取理论。为了避免这种情况,请将AutorizationDao作为参数添加到AuthorizationService的构造函数中:

public function __construct(AuthorizationDao $authDao) {
    $this->authDao = $authDao;
}

以后再用$this->authDao代替new ...东西。

另一种方法是,自行设置容器,这意味着您必须将其注入到服务中,而只能将其设置在您的dao上,这不如上面所示正确地注入dao。

通常,如果您使用的new是使用依赖注入的工具,并且不在工厂(必须知道并保存所有需要的依赖),那么您可能做错了。更具体地说:不要使用创建控制器或服务,new而要注入它们。

(通常只有通过创建实体new,其他都可疑)

但是,如上所述,您可能应该将register方法放入服务中,并将实体管理器也注入服务中。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章