Symfony2: сохранить его как функцию или создать сервис?

У меня есть этот метод в моем контроллере, который из indexAction () вызывается несколько раз. Должен ли я оставить его как есть, или я должен создать класс Helper (Service) для него и других повторно используемых методов, так как я мог бы избежать передачи аргументов, таких как $em в этом случае? Я не могу понять контекст услуг и когда им удобно пользоваться.

public function getProfile($em, $username, $password) {
$dql = $em->createQuery('SELECT Profiles FROM ProjectProjectBundle:Profiles AS Profiles WHERE Profiles.email = :email AND Profiles.password = :password')
->setParameters(array(
'email' => $username,
'password' => $password
));
return $dql->getArrayResult();
}

0

Решение

Прежде всего, знайте это: вы никогда не должны иметь SQL / DQL в своих контроллерах. Никогда.

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

  1. Расскажите доктрине, где находится хранилище сущности Profiles

    SRC / Project / ProjectBundle / Entity / Profiles.php

    /**
    * @ORM\Table()
    * @ORM\Entity(repositoryClass="Project\ProjectBundle\Entity\ProfilesRepository")
    */
    class Profiles {}
    
  2. Создать ProfilesRepository класс и реализация пользовательского поиска

    SRC / Project / ProjectBundle / Entity / ProfilesRepository.php

    namespace Project\ProjectBundle\Entity;
    
    use Doctrine\ORM\EntityRepository;
    
    class ProfilesRepository extends EntityRepository
    {
    /**
    * Find a Profiles entity with the given credentials
    *
    * @return \Project\ProjectBundle\Entity\Profiles|null
    */
    public function findByCredentials($username, $password)
    {
    return $this->findBy(array('email' => $username, 'password' => $password ));
    }
    }
    
  3. Обновите удобный метод в вашем контроллере

    /**
    * Fetch a user's profile
    *
    * @return \Project\ProjectBundle\Entity\Profiles
    */
    private function fetchProfile($username, $password)
    {
    try { // Exception-safe code is good!
    $profilesRepo = $this->getDoctrine()->getEntityRepository('ProjectProjectBundle:Profiles');
    return $profilesRepo->findByCredentials($username, $password);
    }
    catch (\Exception $e)
    {
    // Do whatever you want with exceptions
    }
    return null;
    }
    

Несколько замечаний по предложению

  • Я отказался от DQL в пользу поиска репозитория
  • Я отбросил представление массива строк в пользу представлений сущности. Пока вы на самом деле используете сущности, это предпочтительнее.
  • Я переименовал getProfile() в fetchProfile() так как это лучшее описание того, что делает метод. Я также сделал это частным, потому что это просто хорошая практика безопасного кодирования.
5

Другие решения

Используйте EntityRepositories

// src/YourProjectName/BundleName/Entity/ProfileRepository.php
<?php
namespace YourProjectName\BundleName\Entity;

use Doctrine\ORM\EntityRepository;class ProfileRepository extends EntityRepository
{
public function myGetProfile($username, $password)
{
$dql = $this->getEntityManager()->createQuery('SELECT Profiles FROM ProjectProjectBundle:Profiles AS Profiles WHERE Profiles.email = :email AND Profiles.password = :password')
->setParameters(array(
'email' => $username,
'password' => $password
));

return $dql->getArrayResult();
}
}

Тогда с любых контроллеров ты сможешь сделать

$repository = $em->getRepository('YourBundle:Profile');
$repository->myGetProfile('username', 'password');
1

Я хотел бы использовать хранилище сущностей (только что опубликовал это и понял, что Исаак только что опубликовал, поэтому, пожалуйста, обратитесь)

/ ** Репозиторий Класс ** /

  <?php
namespace YourProjectName\BundleName\Entity;

use Doctrine\ORM\EntityRepository;

class ProfileRepository extends EntityRepository {
public function myGetProfile($username, $password) {
return $this->getEntityManager()
->createQueryBuilder('p')
->from('ProjectProjectBundle:Profiles','p')
->where('p.email = :email')
->andWhere('p.password = :password')
->setParameters(['email' => $email, 'password' => $password])
->getQuery()
->getArrayResult();
}
}

/** In a controller **/
$results = $em->getRepository('ABundle:Profile')->myGetProfile($username, $password);

Также не забудьте добавить этот репозиторий в свой класс enity, иначе он не будет работать

Если у вас есть одна основная функция, которая вызывается, я бы также порекомендовал сделать это с помощью @ParamConverter, используя метод репозитория.

0

Первое, что я хотел бы сделать, это то, что вы сгруппировали вспомогательные классы и службы как одно и то же. У вас может быть глобальный вспомогательный класс для форматирования строк или работы с пути к файлам, но это не будет хорошим сервисом.

Повторное чтение http://symfony.com/doc/current/book/service_container.html предоставил хорошую аналогию с сервисом Mailer. Может быть, в вашем случае вы хотели бы Profiler service управлять своим Profile objects,

$profiler        = $this->get('profile_manager');
$current_profile = $profiler->getProfile();
$other_profile   = $profiler->getProfile('username','password');
0
По вопросам рекламы [email protected]