2015-06-27 62 views
0

我正在尝试在symfony2中创建服务,它将验证会话是否包含某些信息,是否将用户重定向到其他控制器。我想要这段代码作为服务工作,因为我将在许多控制器中使用它。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 

我conntroller文件:

/** 
     * 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"). 

回答

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() 

嗯,这是短暂的xample,但我希望你明白了。

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

服务只是普通的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 
} 

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

最简单的方法就是把它变成config.yml文件,像这样:

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

,或者另一种方式,是创建一个文件(例如services.yml,可在config文件夹),然后将其导入config.yml文件中(该文件的内容是一样的,第一种方式):

imports: 
    - { resource: services.yml } 

或者,你可以创建一个services.yml(的内容文件与第一种方式相同)文件夹内的Resources文件夹,在Extension类(在DependencyInjection文件夹下),load方法下指定它(这种方式需要一些特殊的目录和文件结构,请参阅doc)

class AcmeDemoExtension extends Extension 
{ 
    public function load(array $configs, ContainerBuilder $container) 
    { 
     $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources')); 
     $loader->load('services.yml'); 
    } 
} 

在您的案例,您没有注册您的服务,服务容器找不到它。以上述方式之一注册。