Symfony rest api

Я разрабатываю приложение rest api с symfony в бэкэнде. Моя проблема в том, что когда я пытаюсь запустить запрос GET, приложение запускается, не давая никакого ответа даже через десять минут.

это метод запроса:

/**
 * CounterRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class CounterRepository extends \Doctrine\ORM\EntityRepository
{

    /**
     * @param string $name
     * @param int $date
     * @return mixed
     * @throws \Exception
     */
    public function getValuesByNameAndDate(string $name, int $date)
    {
        $query = $this
            ->createQueryBuilder('c')
            ->leftJoin('c.values', 'v', 'WITH')
            ->addSelect('v')
            ->where('c.name = :name')
            ->andWhere('v.date = :date')
            ->setParameters(
                array(
                    'date' => $date,
                    'name' => $name
                )
            )
            ->getQuery();
        return $query->getResult();
    }

}

Сущность CounterValue:

/**
 * CounterValue
 *
 * @ORM\Table(name = "counter_value")
 * @ORM\Entity(repositoryClass = "AppBundle\Repository\CounterValueRepository")
 */
class CounterValue
{

    /**
     * @var int
     *
     * @ORM\Column(name = "id", type = "integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy = "AUTO")
     */
    private $id;

    /**
     * @var float
     *
     * @ORM\Column(name = "value", type = "float")
     */
    private $value;

    /**
     * @var int
     *
     * @ORM\Column(name = "date", type = "integer")
     */
    private $date;

    /**
     * @var Counter
     *
     * @ORM\ManyToOne(targetEntity = "Counter", inversedBy = "values")
     * @ORM\JoinColumn()
     */
    private $counter;

    /**
     * @var City
     *
     * @ORM\ManyToOne(targetEntity = "City", inversedBy = "values"))
     * @ORM\JoinColumn()
     */
    protected $city;

    public function __construct()
    {
        $date = new \DateTime('-1 day');
        $this->date = strtotime($date->format('d-m-Y'));
    }

    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set value.
     *
     * @param float $value
     *
     * @return CounterValue
     */
    public function setValue($value)
    {
        $this->value = $value;

        return $this;
    }

    /**
     * Get value.
     *
     * @return float
     */
    public function getValue()
    {
        return $this->value;
    }

    /**
     * Set date.
     *
     * @param int $date
     *
     * @return CounterValue
     */
    public function setDate($date)
    {
        $this->date = $date;

        return $this;
    }

    /**
     * Get date.
     *
     * @return int
     */
    public function getDate()
    {
        return $this->date;
    }

    /**
     * @return Counter
     */
    public function getCounter(): Counter
    {
        return $this->counter;
    }

    /**
     * @param Counter $counter
     */
    public function setCounter(Counter $counter): void
    {
        $this->counter = $counter;
    }

    /**
     * @return City
     */
    public function getCity(): City
    {
        return $this->city;
    }

    /**
     * @param City $city
     */
    public function setCity(City $city): void
    {
        $this->city = $city;
    }

}

/**
 * Counter
 *
 * @ORM\Table(name = "counter")
 * @ORM\Entity(repositoryClass = "AppBundle\Repository\CounterRepository")
 */
class Counter
{

    /**
     * @var int
     *
     * @ORM\Column(name = "id", type = "integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy = "AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name = "name", type = "string", length=255, unique=false)
     */
    private $name;

    /**
     * @var XmlFile
     *
     * @ORM\ManyToOne(targetEntity = "XmlFile", inversedBy = "counters", cascade = {"remove"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $xmlFile;

    /**
     * @var ArrayCollection
     *
     * @ORM\OneToMany(targetEntity = "CounterValue", mappedBy = "counter", cascade = {"persist"})
     */
    private $values;

    public function __construct()
    {
        $this->values = new ArrayCollection();
    }

    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name.
     *
     * @param string $name
     *
     * @return Counter
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name.
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set xmlFile
     *
     * @param XmlFile $xmlFile
     */
    public function setXmlFile(XmlFile $xmlFile)
    {
        $this->xmlFile = $xmlFile;
    }

    /**
     * Get xmlFile
     *
     * @return XmlFile
     */
    public function getXmlFile(): XmlFile
    {
        return $this->xmlFile;
    }

    /**
     * @return ArrayCollection
     */
    public function getValues(): ArrayCollection
    {
        return $this->values;
    }

    /**
     * @param ArrayCollection $values
     */
    public function setValues(ArrayCollection $values): void
    {
        $this->values = $values;
    }

    /**
     * Add $value
     *
     * @param CounterValue $value
     */
    public function addValue(CounterValue $value)
    {
        $value->setCounter($this);
        if (!$this->values->contains($value)){
            $this->values->add($value);
        }
    }

}

И, наконец, мой метод в контроллере

$em = $this->get('doctrine.orm.entity_manager');
$counterRep = $em->getRepository('AppBundle:Counter');
return $counterRep->getValuesByNameAndDate('L.IRATHO.E2G.CSFB.ExecSuccOut', 1533600000);

Вы пробовали сузить место в коде, где приложение останавливается? Вы что-нибудь видите в var/logs/*.log? У вас очень большая база данных?

lxg 09.08.2018 08:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
1
1
80
3

Ответы 3

Просто верните такой ответ Json.

public function listAction(Request $request)
{
    try
    {
        $em = $this->get('doctrine.orm.entity_manager');
        $counterRep = $em->getRepository('AppBundle:Counter')->getValuesByNameAndDate('L.IRATHO.E2G.CSFB.ExecSuccOut', 1533600000);
        return new JsonResponse(['success' => true, 'code' => Response::HTTP_OK, 'data' => $counterRep]);
    }
    catch (\Exception $exception)
    {
        return new JsonResponse(['success' => false,'code' => $exception->getCode() ,'message' => $exception->getMessage()]);
    }
}

Действие контроллера должно возвращать экземпляр

Symfony\Component\HttpFoundation\Response

Вы пытаетесь вернуть результат построителя запросов $query->getResult()

Вам нужно изменить его на что-то вроде

public function counterValuesAction(Request $request) {
    try {
        $em = $this->get('doctrine.orm.entity_manager');
        $counterRep = $em->getRepository('AppBundle:Counter');
        $values = $counterRep->getValuesByNameAndDate('L.IRATHO.E2G.CSFB.ExecSuccOut', 1533600000);
    } catch (\Exception $e) {
        return new Response($values);
    }
}

Решение для Symfony 4+:

<?php

namespace App\Controller;

class CounterController extends AbstractController
{
    public function listAction(
        CounterRepository $repository // DI works like this in Controllers...
    ) {
        $result = $repository->getValuesByNameAndDate('L.IRATHO.E2G.CSFB.ExecSuccOut', 1533600000);
        // use JsonResponse object to create JSON response
        return $this->json($result, Response::HTTP_OK); 
    }
}
// routes.yaml
counter_list:
  path: /counter
  controller: App\Controller\CounterController::listAction
  methods: GET

Очистите кеш и попробуйте отправить запрос GET на http: // your-dev-host / counter

Как это работает?

Контроллер

Вам необходимо создать класс контроллера CounterController с функцией действия listAction. Хорошей практикой является добавление постфикса Действие к функции действия.

Вы можете определить службы или другие объекты DI как параметры в функциях действий. Д. Я установлю это. Например:

class MyController extends AbstractController
{
    public function listAction(
        Request $request,
        SerializerInterface $serializer,
        ValidatorInterface $validator,
        CounterRepository $repository
    ) {
        // ...
    }
}

Чтобы отправить хороший ответ с JSON и всеми необходимыми заголовками, вам необходимо использовать функцию AbstractController :: json. Он создает объект JsonResponse. Вы можете проверить его реализацию.

Более подробную информацию о контроллерах Symfony вы можете найти в этой статье https://symfony.com/doc/current/controller.html

Маршрутизация

Следующим шагом будет создание маршрута для вашего нового действия контроллера. Сделать это можно двумя способами:

  1. Добавление записи в файл config / routes.yaml, как это сделал я
  2. Используйте аннотации (аннотации - плохая практика, потому что комментарии не должны нарушать работу программы)

Подробнее о маршрутизации читайте в статье https://symfony.com/doc/current/routing.html.

Это не работает для меня! Как мне отладить это?

Во-первых, не паникуйте и прочтите сообщение об ошибке. Также вы можете проверить, работает ли маршрутизация. Вы можете сделать это с помощью команды

$ bin/console debug:router
 ----------------------- -------- -------- ------ ------------------------------------- 
  Name                    Method   Scheme   Host   Path                                 
 ----------------------- -------- -------- ------ ------------------------------------- 
  _preview_error          ANY      ANY      ANY    /_error/{code}.{_format}             
  register_token          POST     ANY      ANY    /auth/register                       
  refresh_token           POST     ANY      ANY    /auth/refresh                        
  auth_login              POST     ANY      ANY    /auth/login                          
  restroom_list           GET      ANY      ANY    /api/v1/restroom                      
 ----------------------- -------- -------- ------ ------------------------------------- 

В таблице вам нужно проверить ваш новый URL и то, как его видит Symfony.

Во-вторых, попробуйте отправить запрос по этому URL-адресу с помощью curl и проверьте ответ.

$ curl http://localhost/auth/login

Пожалуйста, добавьте пояснение к своему ответу, чтобы другие могли извлечь из него урок - что вы изменили и почему?

Nico Haase 25.06.2020 14:14

Ты серьезно? Stackoverflow - мертвец :) ... этот вопрос уже устарел

Nikolay Kornushkov 25.06.2020 23:45

Другие вопросы по теме