У меня есть этот метод в моем контроллере, который из 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();
}
Прежде всего, знайте это: вы никогда не должны иметь SQL / DQL в своих контроллерах. Никогда.
Во-вторых, у вас есть несколько вариантов, но я только обрисую один. Я предполагаю, что у вас есть определенные сущности, поэтому давайте начнем с опций, основанных на этом.
Расскажите доктрине, где находится хранилище сущности Profiles
SRC / Project / ProjectBundle / Entity / Profiles.php
/**
* @ORM\Table()
* @ORM\Entity(repositoryClass="Project\ProjectBundle\Entity\ProfilesRepository")
*/
class Profiles {}
Создать 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 ));
}
}
Обновите удобный метод в вашем контроллере
/**
* 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;
}
Несколько замечаний по предложению
getProfile()
в fetchProfile()
так как это лучшее описание того, что делает метод. Я также сделал это частным, потому что это просто хорошая практика безопасного кодирования.Используйте 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');
Я хотел бы использовать хранилище сущностей (только что опубликовал это и понял, что Исаак только что опубликовал, поэтому, пожалуйста, обратитесь)
/ ** Репозиторий Класс ** /
<?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, используя метод репозитория.
Первое, что я хотел бы сделать, это то, что вы сгруппировали вспомогательные классы и службы как одно и то же. У вас может быть глобальный вспомогательный класс для форматирования строк или работы с пути к файлам, но это не будет хорошим сервисом.
Повторное чтение 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');