Symfony4资源控制器

时间:2018-12-20 16:52:42

标签: api symfony symfony4 api-platform.com

我正在symfony4下开发一个API,希望我可以创建一个父控制器,该控制器可以用来调用将在另一个控制器中重复的函数。这是我想从父控制器扩展的控制器:

我的DeliveryController:

<?php

namespace App\Controller;

use App\Entity\DeliveryMan;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Routing\Annotation\Route;

/**
 * Class AuthController
 * @package App\Controller
 * @Route("/api")
 */
class DeliveryController extends AbstractController
{
    /**
     * @Route(
     *     name="api_delivery_man_post",
     *     path="/delivery_man",
     *     methods={"POST"},
     *     defaults={
     *         "_api_resource_class"=DeliveryMan::class,
     *         "_api_collection_operation_name"="post"
     *     }
     * )
     */
    public function postAction(DeliveryMan $data, UserPasswordEncoderInterface $encoder): DeliveryMan
    {
        return $this->encodePassword($data, $encoder);
    }

    protected function encodePassword(DeliveryMan $data, UserPasswordEncoderInterface $encoder): DeliveryMan
    {
        $encoded = $encoder->encodePassword($data, $data->getPassword());
        $data->setPassword($encoded);

        return $data;
    }
}

我的AuthController:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use App\Entity\User;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

/**
 * Class AuthController
 * @package App\Controller
 * @Route("/api")
 */
class AuthController extends AbstractController
{
    /**
     * @Route(
     *     name="api_users_post",
     *     path="/users",
     *     methods={"POST"},
     *     defaults={
     *         "_api_resource_class"=User::class,
     *         "_api_collection_operation_name"="post"
     *     }
     * )
     */
    public function postAction(User $data, UserPasswordEncoderInterface $encoder): User
    {
        return $this->encodePassword($data, $encoder);
    }

    protected function encodePassword(User $data, UserPasswordEncoderInterface $encoder): User
    {
        $encoded = $encoder->encodePassword($data, $data->getPassword());
        $data->setPassword($encoded);

        return $data;
    }
}

可以看出,我将2个不同的控制器中的2个相同的动作称为唯一的区别,那就是道路的实体和路径。

因此,我正在考虑创建一个从AbstractController扩展的ResourceController父控制器,以及从ResourceController扩展的子控制器,但是我不知道如何在父控制器中创建方法并在子控制器。

如果某人已经做过,那我就是接受者:)谢谢您的帮助。

编辑结果ResourceController:

<?php

namespace App\Controller;

use App\Entity\DeliveryMan;
use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class ResourcesController extends AbstractController
{
    private $encoder;

    public function __construct(UserPasswordEncoderInterface $encoder)
    {
        $this->encoder = $encoder;
    }

    public function encodePassword(User $data): User
    {
        $encoded = $this->encoder->encodePassword($data, $data->getPassword());
        $data->setPassword($encoded);

        return $data;
    }

    public function encodePasswordDelivery(DeliveryMan $data): DeliveryMan
    {
        $encoded = $this->encoder->encodePassword($data, $data->getPassword());
        $data->setPassword($encoded);

        return $data;
    }
}

1 个答案:

答案 0 :(得分:0)

只需将ResourceController扩展到Symfony AbstractController。

在此处编写2个共享方法,然后在任何扩展ResourceController的Controller中,都可以像通常调用类方法一样调用它们:使用$ this

class ResourceController extends AbstractController
{   
    private $encoder;

    public function __construct(UserPasswordEncoderInterface $encoder)
    {
        $this->encoder = $encoder;    
    }

    public function encodePassword(Object $data): Object
    {
        $encoded = $this->encoder->encodePassword($data, $data->getPassword());
        $data->setPassword($encoded);

        return $data;
    }
}

class AuthController extends ResourceController
{
    public function someAction(User $data)
    {
        return $this->encodePassword($data);
    }
}

我还建议您使用User和DeliveryMan将实现的getPassword方法编写一个接口。不仅您将确保实现该方法,而且还可以键入提示,例如AuthenticatedEntityInterface而不是Object