symfony2中的服务 - 服务文件应该如何?

时间:2015-06-27 17:43:22

标签: symfony

我正在尝试在symfony2中创建服务,该服务将验证会话是否包含某些信息,如果没有将用户重定向到另一个控制器。我想要这段代码作为服务工作,因为我将在许多控制器中使用它。

我有问题,因为Symfony2上的手册没有提供服务文件应该是什么样子的信息。它应该是一个普通的php类吗?

请在下面找到我的文件转储,其中包含我收到的错误信息。

\AppBundle\Services我创建包含以下内容的文件my_isbookchosencheck.php

<?php

namespace AppBundle\my_isbookchosencheck;

class my_isbookchosencheck
{
    public function __construct();
    {
        $session = new Session();
        $session->getFlashBag()->add('msg', 'No book choosen. Redirected to proper form');
        if(!$session->get("App_Books_Chosen_Lp")) return new RedirectResponse($this->generateUrl('app_listbooks'));
    }
}

我的service.yml

my_isbookchosencheck:
        class:         AppBundle\Services\my_isbookchosencheck

我的控制文件:

/**
        * This code is aimed at checking if the book is choseen and therefore whether any further works may be carried out
        */
        $checker = $this->get('my_isbookchosencheck');

错误:

FileLoaderLoadException in FileLoader.php line 125: There is no extension able to load the configuration for "my_isbookchosencheck" (in C:/wamp/www/symfony_learn/app/config\services.yml). Looked for namespace "my_isbookchosencheck", found "framework", "security", "twig", "monolog", "swiftmailer", "assetic", "doctrine", "sensio_framework_extra", "fos_user", "knp_paginator", "genemu_form", "debug", "acme_demo", "web_profiler", "sensio_distribution" in C:/wamp/www/symfony_learn/app/config\services.yml (which is being imported from "C:/wamp/www/symfony_learn/app/config\config.yml").

3 个答案:

答案 0 :(得分:1)

services:    
    my_isbookchosencheck:
        class:         AppBundle\Services\my_isbookchosencheck
在您的services.yml中

,并检查您是否使用了正确的命名空间。

你的班级很好,它应该有效,但我建议你使用 symfony2会话服务而不是自己创建会话对象,您可以将其作为构造函数参数传递:

<?php

// namespace edited
namespace AppBundle\Services;

use Symfony\Component\HttpFoundation\Session\Session;

class my_isbookchosencheck
{
    public function __construct(Session $session);
    {
        $session->getFlashBag()->add('msg', 'No book choosen. Redirected to proper form');
        if(!$session->get("App_Books_Chosen_Lp")) return new RedirectResponse($this->generateUrl('app_listbooks'));
    }
}

然后相应地编辑您的services.yml,因此服务容器将注入会话对象:

services:    
    my_isbookchosencheck:
        class:         AppBundle\Services\my_isbookchosencheck
        arguments:     [@session]

同时查看他的问题: How do you access a users session from a service in Symfony2?

答案 1 :(得分:1)

你犯的错误很少,我将简要解释一下,我将举例说明你想要创建的服务。

  • 您在AppBundle\Services中创建了服务,但您的命名空间的注册方式不同 - namespace AppBundle\Services\my_isbookchosencheck;。它应该是namespace AppBundle\Services;。我还建议你在创建目录时使用单数名称 - 在这种情况下Service会更好,而不是Services

  • 您直接使用__constructor应用某些逻辑并返回结果。更好的方法是创建一个自定义方法,必要时可以访问该方法。

  • 您正在创建Session的新实例,这意味着您将无法访问之前添加并存储在会话中的任何内容。这里正确的方法是注入RequestStack,其中包含当前Request并从那里获取会话。

  • 我相信您也注册了您的服务错误。在services.yml文件中,它应位于services:选项下。这就是您收到错误的原因。

所以,让我们看看您的服务应该如何。

<强> services.yml

services:
    book_service:
        class: AppBundle\Service\BookService
        arguments:
            - @request_stack
            - @router

<强> BookService.php

namespace AppBundle\Service;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\RouterInterface;

class BookService {

    /* @var $request Request */
    private $request;

    /* @var $router RouterInterface */
    private $router;

    public function __construct(RequestStack $requestStack, RouterInterface $router) {
        $this->request = $requestStack->getCurrentRequest();
        $this->router = $router;
    }

    public function isBookChoosen() {
        $session = $this->request->getSession();

        // Now you can access session the proper way.
        // If anything was added in session from your controller
        // you can access it here as well.

        // Apply your logic here and use $this->router->generate()
    }

}

现在在您的控制器中,您可以像这样使用它:

$this->get('book_service')->isBookChoosen()

这是一个简短的例子,但我希望你有这个想法。

答案 2 :(得分:1)

服务只是常规的PHP类,没什么特别的。但您必须注册才能被系统识别。以下是您执行此操作的步骤,

创建常规PHP类(如果需要,可以注入其他服务)

namespace Acme\DemoBundle\Service;

class MyService
{
    private $session;

    public function _construct(SessionInterface $session /* here we're injecting the session service which implements the SessionInterface */)
    {
        $this->session = $session;
    }

    // other methods go here, which holds the business logic of this class
}

好的,我们创建了一个类,我们需要将它注册为能够通过服务容器使用它,在这里你是如何做到的:

最简单的方法是将其放入config.yml文件中,如下所示:

services:
    my_service:
        class: Acme\DemoBundle\Service\MyService
        arguments:
           - @session

或另一种方式是创建一个文件(例如services.yml,可能在config文件夹中),并将其导入config.yml文件中(文件的内容是与第一种方式相同):

imports:
    - { resource: services.yml }

或者,您可以在捆绑的services.yml文件夹中创建Resources(文件的内容与第一种方式相同)文件,在{{1你的Extension类的方法(在DependencyInjection文件夹下),(这种方式需要一些特殊的目录和文件结构,在doc中阅读它)

load

在您的情况下,您没有注册您的服务,服务容器无法找到它。通过上述方式之一注册。