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 响应,因此从另一个控制器调用控制器通常不是一个好主意,因为您可能不需要该响应,而只需要实现方法。
这也是您应该将可重用代码移至服务的原因。控制器实际上应该只有:
- 从请求中提取数据
- 调用一些服务
- 使用结果渲染模板
命令相同。这些服务是您应用程序的核心。控制器或命令之间的水平通信大多不是一个好主意(当然只有一些代理或包装器)。
以下是您的代码的一些想法:
动作本身就是太多不可读的代码。如果您通过 symfony 表单获取上传的文件,请阅读此
如果您使用表单,请不要直接访问请求。原因是,只有创建表单(和数据 class)的构建器或 Type
class 知道输入字段的名称并将它们映射到数据 class.您应该只使用数据 class。然后你会得到一个很好的 UploadedFile
对象来检查所有内容,但也会将检查移至服务。
首先,我是第一次尝试使用服务...(实际上,如果 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 响应,因此从另一个控制器调用控制器通常不是一个好主意,因为您可能不需要该响应,而只需要实现方法。
这也是您应该将可重用代码移至服务的原因。控制器实际上应该只有:
- 从请求中提取数据
- 调用一些服务
- 使用结果渲染模板
命令相同。这些服务是您应用程序的核心。控制器或命令之间的水平通信大多不是一个好主意(当然只有一些代理或包装器)。
以下是您的代码的一些想法:
动作本身就是太多不可读的代码。如果您通过 symfony 表单获取上传的文件,请阅读此
如果您使用表单,请不要直接访问请求。原因是,只有创建表单(和数据 class)的构建器或
Type
class 知道输入字段的名称并将它们映射到数据 class.您应该只使用数据 class。然后你会得到一个很好的UploadedFile
对象来检查所有内容,但也会将检查移至服务。