Symfony2 - 如何将此搜索功能实现为服务?

时间:2014-04-01 20:57:23

标签: symfony search service helper

我想将此代码用作服务,因此我不会在每个控制器中重复此操作。我将如何将其用作服务,以便其功能如下?

我已经阅读了一些文档并将其设置为服务,但我不确定这应该如何将变量传递到twig模板中。

我目前正在以$ search = $ this-> get(“search”) - > search();但是当我传入'search'=>时出现错误$搜索树枝。

(ContextErrorException:Catchable Fatal Error:传递给Acme \ ProjectBundle \ Services \ Search :: search()的参数1必须是Acme \ ProjectBundle \ Services \ Request的实例,没有给出,在/ var /中调用www / html / Project / src / Acme / ProjectBundle / Controller / PageController.php在第30行并在/var/www/html/Project/src/Acme/ProjectBundle/Services/Search.php第8行中定义

执行此操作并在控制器中调用它的正确方法是什么?

没有服务的原始索引控制器

public function indexAction(Request $request)
{

    // Search code
    $results = null;
    $query = $request->query->get('q');

    if (!empty($query)) {
        $em = $this->getDoctrine()->getManager();

        $results = $em->createQueryBuilder()
            ->from('AcmeProjectBundle:Blog', 'b')
            ->select('b')
            ->where('b.title LIKE :search')
            ->setParameter(':search', "%${query}%")
            ->getQuery()
            ->getResult();
    }

    return $this->render('AcmeProjectBundle:Default:index.html.twig', array(
        'query'        => $query,
        'results'      => $results,
    ));
}

服务搜索类

class Search
{
   public function search(Request $request)
   {
      $results = null;
      $query = $request->query->get('q');

      if (!empty($query)) {
          $em = $this->getDoctrine()->getManager();
          $results = $em->createQueryBuilder()
            ->from('AcmeProjectBundle:Blog', 'b')
            ->select('b')
            ->where('b.title LIKE :search')
            ->setParameter(':search', "%${query}%")
            ->getQuery()
            ->getResult();
      }

      return array(
          'query'   => $query,
          'results' => $results,
       );
   }
}

index.html.twig

{% block search %}
<form action="{{ path('acme_project_search') }}" method="GET">
    <label><input type="search" name="q" value={{ query }}></label>
    <input type="submit" value="Search">
</form>
<br>
{% endblock %}

config.yml

services:
   search:
      class: Acme\ProjectBundle\Services\Search

2 个答案:

答案 0 :(得分:0)

如果您尝试注入请求服务,最好注入request_stack服务,并通过调用getCurrentRequest()

访问当前请求
class Search
{
    protected $request;

    public function __construct(RequestStack $requestStack)
    {
        $this->request = $requestStack->getCurrentRequest();
        //Do any kinds of initializing you need
    }

    public function mySearch()
    {
       $results = null;
       $query = $this->request->query->get('q');
       //Do your search base on $query
       //I suggest to send the container instead of RequestStack because you want to do search by using EntityManger, too
       //Return the results
    }
}

并按如下所示更改service.yml,并将范围设置为“request”

services:
   search:
      class:     Acme\ProjectBundle\Services\Search
      arguments: ["@request_stack"]
      scope: "request"

您还可以选择将容器作为参数发送到您的服务,并在您的服务中使用container->getRequset()

答案 1 :(得分:0)

您需要将Request注入您的服务:

search:
    class: Acme\ProjectBundle\Services\Search
    scope: request
    arguments: [@request]

然后在你的Search课程中:

private $request;

public function __construct(Request $request)
{
    $this->request = $request;
}

之后,只要您需要访问服务中的Request,就可以使用$this->request。并在搜索功能中删除Request $request参数注入。

<强>更新

您的indexAction将如下所示:

public function indexAction(Request $request)
{
    return $this->render('AcmeProjectBundle:Default:index.html.twig',
        $this->get('search')->search()
    );
}