Symfony - вернуть только один параметр - PullRequest
0 голосов

Я написал код, который должен получить один параметр, число (строку) ..

Мой контроллер.

   /**
 * @Route("/activate", name="activate")
 * @return \Symfony\Component\HttpFoundation\JsonResponse
 */
public function getActivate()
{
        $data = array(
            'number' => '123456'
        );
        return $this->success($data);
}

Я не знаю, это лучший способ написать функцию запросав моем сервисе, а затем позвонить на мой контроллер или это правильный путь.Если запрос лучше, то как мне начать?Нравится:

public function getNumber($data)
{
    $number = $this->getRepository()
        ->createQueryBuilder('n')
        ->select('n')
        ->where('n.data = :data').....

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Ответ @revengeance твердый, но я также добавил бы, что он также будет зависеть от того, откуда берется число $.Если он статичен, как в вашем примере, то передача его в службу совершенно разумна.

Однако, если это происходит из параметров URL:

/**
 * @Route("/activate/{id}", name="activate")
 * @return \Symfony\Component\HttpFoundation\JsonResponse
 */

, тогда вы можете ввести подсказкусущность с ParamConverter, и пара уже существует для автоматического выполнения некоторых задач (вы также можете написать свою собственную для других задач).

/**
 * @Route("/activate/{id}", name="activate")
 * @return \Symfony\Component\HttpFoundation\JsonResponse
 */
public function activateAction(Post $post)
{
    // other security checks - do we have permission to activate this?
    // ....  

    return $this->activatePost($post);  // do something to turn on the entity
}

public function activatePost(Post $post)
{
    $post->setActive(true);
    $post->persist(true);

    return $post;
}

Здесь сущность Post находится по ее первичному ключу -post.id - и полностью сформированный объект передается в действие контроллера, где его можно использовать.Если такого элемента нет, платформа выдает ошибку 404-Not Found для вас.

0 голосов
/ 31 мая 2018

Нет, не лучше размещать ваш запрос внутри службы.

В общем, следуйте по крайней мере этим 3 правилам:

1) Не размещайте бизнес-логику и запросы в вашем контроллере.Контроллер должен вызывать только сервисные функции

2) Как следует из пункта 1, сервисы должны взаимодействовать с репозиториями.

3) Запросы должны находиться в репозиториях.

Поэтому Controller-> Service-> Repository

Имейте в виду, что иногда может быть полезно вызвать некоторую функцию репозитория из контроллера (если вам не требуется дополнительная работа с результатомфункция репозитория, и вы можете вернуть его прямо)

Примеры того, как я работаю.

В следующем примере, чтобы добиться этого

1) Используйте Dependency Injection, чтобы получить сервис в вашем контроллере. 2) Назовите его

<?php

namespace AppBundle\Controller;

use AppBundle\Service\MapService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Class MainPageController
 * @package AppBundle\Controller
 */
class MainPageController extends Controller
{
    /**
     * @var EntityManagerInterface
     */
    private $em;

    /**
     * @var MapService
     */
    private $mapService;

    /**
     * MainPageController constructor.
     * @param EntityManagerInterface $em
     * @param MapService $ms
     */
    public function __construct(EntityManagerInterface $em, MapService $ms)
    {
        $this->em = $em;
        $this->mapService = $ms;
    }

    /**
     * @param Request $request
     * @return Response
     */
    public function indexAction(Request $request)
    {
        $mapData = $this->mapService->prepareMapInformation();

        return $this->render('@App/pages/index.html.twig', [
            'mapData' => $mapData,
        ]);
    }
}

Второй пример - Сервис .

1) Введите нужный репозиторий или введите объектМенеджер внутри сервиса и получит репозиторий через него 2) Вызовите нужную функцию представителя 3) Поработайте с ней и верните

public function prepareMapInformation(): array
{
   $result = [];
   $activeCities = $this->cityRepository->getAllActiveCities();
   $companyInformation = $this->companyRepository
   ->getInformationForMap();

foreach ($activeCities as $oneCity) {
    /** @var City $oneCity */
    $push = [];
    $push['latitude'] = $oneCity->getLatitude();
    $push['longitude'] = $oneCity->getLongitude();
    $push['nameLocation'] = $this->determineNameLocation($oneCity- 
    >getNameLocation());
    $push['companies'] = $this->getCompanies($companyInformation, 
    $oneCity);

    if (!empty($push['companies'])) {
        $result[$oneCity->getName()] = $push;
    }
}

return $result;
}

Третий пример - Репозиторий.

<?php

namespace AppBundle\Repository;

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr\Join;

/**
 * Class CityRepository
 * @package AppBundle\Repository
 */
class CityRepository extends EntityRepository
{
    /**
     * @return array
     */
    public function getAllCitiesAssoc(): array
    {
        return $this->_em->createQueryBuilder()
            ->select('c')
            ->from('AppBundle:City', 'c', 'c.name') // third param is index by (it creates assoc array with keys of city names)
            ->getQuery()
            ->getResult();
    }

    /**
     * @return array
     */
    public function getAllActiveCities(): array
    {
        return $this->findBy(['active' => 1]);
    }
}

РЕДАКТИРОВАТЬПОСЛЕ @Alister Bulman answer.

Да, вы можете использовать ParamConverter, если вам не нужна дополнительная логика для вашей сущности и вы просто не хотите возвращать ее данные для просмотра.Но это не так хорошо в случаях, когда вам нужно выполнить дополнительную логику с данными, потому что тогда вы должны сделать это в контроллере или передать объект на обслуживание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...