Symfony 服务 --> 正确用法?

Symfony services --> correct usage?

首先,我是第一次尝试使用服务...(实际上,如果 s.o。可以提供有关如何、何时以及为何使用它的简短信息。很好 ;-) )

但现在针对我的具体情况:

我写了两个控制器: 一个用于将 xlsx 文件上传到服务器 一个用于将 xlsx 数据导入 DB

我现在要做的是将上传控制器的(上传)路径传递给导入控制器。我使用导入即服务是否正确?

代码如下所示...

class FileUploadController extends Controller

/**
* @Route("/upload", name="upload")
* @Security("has_role('ROLE_ADMIN')")
*/

public function uploadAction(Request $request){
    $companyid    = $this->getUser()->getCompany();

    if ($request->getMethod() == 'POST'){
        $file = $request->files->get('xls');
        $uploadedURL = '';
        if(($file instanceof UploadedFile) && $file->getError()=='0'){
            if(!($file->getSize()<20000)){
                $originalName = $file->getClientOriginalName();
                $name_array = explode('.',$originalName );
                $file_type = $name_array[(sizeof($name_array)-1)];
                $valid_filetypes = array('xls', 'xlsx');
                if(in_array(strtolower($file_type), $valid_filetypes)){

                    $document = new Document();
                    $document->setFile($file);
                    $document->setSubDirectory('uploads');
                    $document->processFile();
                    $uploadedURL=$uploadedURL=$document->getUploadDirectory().DIRECTORY_SEPARATOR.$document->getSubDirectory().DIRECTORY_SEPARATOR.$file->getBasename();



                }else{
                    echo "Wrong File Ending";
                }
            }else {
                echo "File to big";
            }

        }else{
            print_r('File Error');
            die;;
        }

        $this->get("dataimport.service")->importIndexAction($uploadedURL);

    }else{


        return $this->render(bla)

DataImportController 为:

class DataImportController extends Controller

 /**
* @param ContainerInterface $container
*/
 public function __construct(ContainerInterface $container)
 {
  $this->container = $container;
}

/**
* @Security("has_role('ROLE_ADMIN')")
*/
public function importIndexAction($path)
{    


  $companyid    = $this->getUser()->getCompany();
  $em           = $this->getDoctrine()->getManager();
  $file         = $this->defineFilePathAction($path);
  $reader       = $this->readExcelAction($file);
  $accountarray = $this->getAccountsArrayAction($companyid);
  $this->importAccountsAction($companyid, $reader, $accountarray, $em);

}
....
/**
    * Get a service from the container
    *
    * @param string The service to get
    */
      public function get($service)
      {
        return $this->container->get($service);
      }

services.yml

services:
dataimport.service:
    class: AppBundle\Controller\DataHandling\DataImportController
    arguments: [@service_container]

感谢您的帮助!

在 Symfony 中,控制器和服务起初只是一个 class。控制器的 public 方法用于获取输入并生成 Response(输出)(顺便说一句,注入 Request 已被弃用,您必须使用来自 request_stack).服务是 DI 容器之外的对象,完全没有约束。

由于控制器的方法必须生成并 return 响应,因此从另一个控制器调用控制器通常不是一个好主意,因为您可能不需要该响应,而只需要实现方法。

这也是您应该将可重用代码移至服务的原因。控制器实际上应该只有:

  • 从请求中提取数据
  • 调用一些服务
  • 使用结果渲染模板

命令相同。这些服务是您应用程序的核心。控制器或命令之间的水平通信大多不是一个好主意(当然只有一些代理或包装器)。

以下是您的代码的一些想法:

  1. 动作本身就是太多不可读的代码。如果您通过 symfony 表单获取上传的文件,请阅读此

  2. 如果您使用表单,请不要直接访问请求。原因是,只有创建表单(和数据 class)的构建器或 Type class 知道输入字段的名称并将它们映射到数据 class.您应该只使用数据 class。然后你会得到一个很好的 UploadedFile 对象来检查所有内容,但也会将检查移至服务。