在Symfony 3.4中使用这样的服务是否正确?

时间:2018-12-20 15:09:21

标签: php symfony

那么这是允许使用的还是将服务注入控制器的构造函数中更好?我知道有更好的方法,但是为了懒惰,我可以这样做吗?

class someController extends Controller 
{
    /**
     * @Route("/test")
     */
    public function someFunction() 
    {
        $manager = $this->getDoctrine();
        $service = new someService($manager);

        $all =  $service->getAll();
        dump($all);exit;
    }
}


------------------------------------------------
use Doctrine\Common\Persistence\ManagerRegistry;

class someService implements someServiceInterface 
{
   /**
    * @var ManagerRegistry
    */
    private $manager;

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

    public function getAll() 
    {
        return $this->manager->getRepository(SomeEntity::class)->findAll();
    }
}

4 个答案:

答案 0 :(得分:1)

虽然不正确(您的应用程序不会崩溃),但不建议这样做。 建议您阅读此page

您已经猜到可以将服务注入构造函数中。 只需添加

即可在您的config.yml中启用它
App\Controller\:
    resource: '../../Controller'
    tags: ['controller.service_arguments']

当您的服务需要其他依赖项时,它将为您解决很多麻烦和重构

答案 1 :(得分:0)

您可以使用

将服务直接注入到控制器中
public function someFunction(someService $service) //I do that because I'm lazier than you.
{
    //your code
}

自动接线将搜索并注入您的服务。

在services.yaml中,您可以设置:

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false

有关自动接线的更多信息,请参见documentation

答案 2 :(得分:0)

class SomeController extends AbstractController // Controller deprecated since 4.0
{
    /**
     * @Route("/test")
     */
    public function someFunction(SomeServiceInterface $someService) // that's all what you need, "autowire: true" by default since 3.4
    {
        $manager = $this->getDoctrine();
        $all =  $someService->getAll();
        dump($all);exit;
    }
}


------------------------------------------------
use Doctrine\Common\Persistence\ManagerRegistry;

class SomeService implements SomeServiceInterface
{
    /**
     * @var ManagerRegistry
     */
    private $manager;

    public function __construct(ManagerRegistry $manager) // autowire
    {
        $this->manager = $manager;
    }

    public function getAll()
    {
        return $this->manager->getRepository(SomeEntity::class)->findAll();
    }
}

答案 3 :(得分:0)

我想您的服务有问题,因为您需要在其中注入实体管理器。请注意,这没有错。这是应该起作用的代码:

假设我们注入了服务:

    for root, dirs,files in sorted(os.walk(path+ "/", topdown=False)):  # root

        for lab in dirs:  # level 1 
            new_path=path+category+'/'+lab+'/'
            for ro,dir,f in os.walk(new_path): #level 2
                for dr in dir:
                    for ri, dir, file in os.walk(new_path+'/'+dr): #level 3 
                        os.chdir(new_path+'/'+dr)
                        text_file=glob.glob("*.txt")

您可以直接在Controller的构造函数中进行注入,但是这里我使用动作注入see documentation

这是您的服务外观:

// Better use camel case with upper first letter
class SomeController extends Controller 
{    
    /**
     * @Route("/test")
     */
    public function someFunction(SomeService $someService) 
    {
        $all =  $someService->getAll();
        dump($all);exit;
    }
}

这在Symfony 4.x设置中是开箱即用的,因为默认情况下它们定义了服务自动加载和自动连线。 Symfony 3.4 see documentation中提供了哪些功能。

但是要手动配置所有这些,您可能需要以下配置:

class SomeService implements SomeServiceInterface 
{
   /**
    * @var EntityManagerInterface
    */
    private $manager;

    // Type hinting matters here!
    public function __construct(EntityManagerInterface $manager)
    {
        $this->manager = $manager;
    }

    public function getAll() 
    {
        return $this->manager->getRepository(SomeEntity::class)->findAll();
    }
}

最后,如果您正在寻找一种制作懒惰服务的方法,则它是Symfony依赖注入组件的功能。再次参见documentation over here