向Laravel应用程序添加服务层的效果

Kim*_*nce 2 service-layer laravel

我使用Zend Framework进行开发已有多年,现在正在学习Laravel。

在我以前的应用程序中,我通常有一个由控制器调用的服务层。服务层位于映射器和域模型的顶部,负责某些应用程序逻辑,引发事件,某些输入过滤等。

我为什么不应该在Laravel中实现服务层?在到目前为止的示例中,控制器直接与域对象(或更准确地说,是活动记录)一起工作。

如果我的Laravel控制器调用我的服务层,我会失去Laravel的任何优势吗?(据我所知,我仍然可以使用Route / Model绑定)。

作为第二个问题-实施我的服务层的最佳方法是什么?作为服务提供商的集合,也许吗?

Kev*_*ers 7

我还从Zend转到Laravel,错过了我的服务。为了安抚自己,我实现了一个位于命名空间App \ Services中的Service命名空间。我在那里完成所有模型/验证处理。我没有遇到任何功能损失。

我的控制器布局示例:

<?php
namespace App\Http\Controllers;

use App\Services\Contact as ContactService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Lang;

class IndexController extends Controller
{

    /**
     * Create a new controller instance.
     *
     * @param Request $request
     * @return void
     */
    public function __construct(Request $request)
    {
        $this->_request  = $request;
    }

    /**
     * Standard contact page
     * 
     * @return contact page
     */
    public function contact(ContactService $contactService)
    {
        $errors  = null;
        $success = false;
        if ($this->_request->isMethod('post')) {
            $validator            = $contactService->validator($this->_request->all());
            if ($validator->fails()) {
                $errors = $validator->errors();
            } else {
                $contactService->create($validator->getData());
                $success = true;
            }
        }
        return view('pages/contact', ['errors' => $errors, 'success' => $success]);
    }
}
Run Code Online (Sandbox Code Playgroud)

这些服务返回验证器,处理杂项,基本上完成了我不想在Controller中看到的所有内容,就像在Zend项目中一样。

服务示例:

<?php
namespace App\Services;

use Validator;
use Mail;
use App\Models\Contact as ContactModel;

class Contact
{

    /**
     * Get a validator for a contact.
     *
     * @param  array $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    public function validator(array $data)
    {
        return Validator::make($data, [
                'email'     => 'required|email|max:255',
                'phone'     => 'max:255',
                'firstName' => 'required|max:255',
                'lastName'  => 'required|max:255',
                'message'   => 'required'
        ]);
    }

    /**
     * Create a new contact instance after a valid form.
     *
     * @param  array $data
     * @return ContactModel
     */
    public function create(array $data)
    {
        //Handle or map any data differently if needed, just for illustration
        $data = [
            'email'     => $data['email'],
            'firstName' => $data['firstName'],
            'lastName'  => $data['lastName'],
            'language'  => $data['language'],
            'phone'     => $data['phone'],
            'message'   => $data['message']
        ];

        // Send an email
        Mail::send('emails.contact', ['data' => $data], function ($m) use ($data) {
            $m->from(config('mail.from.address'), config('mail.from.name'));
            $m->to(env('MAIL_TO', 'hello@world.com'), env('MAIL_TO'))->subject('Contact form entry from: ' . $data['firstName']);
        });

        return ContactModel::create($data);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 嘿你,等等!我建议你阅读 laravel 的文档,我认为这不是实现服务层模式的正确方法。我看到您使用服务命名空间来完成表单请求的工作,并且在 laravel 中已经存在。因此,如果 Kim Prince 或其他人这样做,他们就会失去 Laravel 的优势。https://medium.com/@kamerk22/the-smart-way-to-handle-request-validation-in-laravel-5e8886279271 (2认同)