在Laravel4上使用我自己的服务

时间:2014-07-26 17:30:53

标签: service laravel laravel-4

在我的应用中,我使用ajax测试Google Directions API,但由于我只是在测试routes.php文件中的所有逻辑。现在我想以正确的方式做事并有三层:路线,控制器和服务。

所以在路线中我告诉Laravel应该执行哪种方法:

Route::get('/search', 'DirectionsAPIController@search');

该方法只返回服务应该返回的内容:

class DirectionsAPIController extends BaseController {
    public function search() {
        $directionsSearchService = new DirectionsSearchService();
        return $directionsSearchService->search(Input::all());
    }
}

我在app/libraries/Services/Directions中创建了该服务并将其称为DirectionsSearchService.php并复制了我在路线中开发的所有逻辑:

class DirectionsSearchService {
    public function search($input = array()) {
        $origin = $input['origin'];
        $destination = $input['destination'];
        $mode = $input['mode'];

        // do stuf...

        return $data;
    }
}

我读了the docssome place else(以及this)并做了我应该做的事情来注册服务:

class DirectionsAPIController extends BaseController {
    public function search() {
        App::register('libraries\Services\Directions\DirectionsSearchService');
        $directionsSearchService = new DirectionsSearchService();
        return $directionsSearchService->search(Input::all());
    }
}

// app/libraries/Services/Directions/DirectionsSearchService.php
use Illuminate\Support\ServiceProvider;

class DirectionsSearchService extends ServiceProvider {
}

我还尝试将libraries\Services\Directions\DirectionsSearchService添加到providers中的app/config/app.php数组。

但是,我收到此错误:

  

HP致命错误:类   '库\ SERVICES \地图\ DirectionsSearchService'找不到   第549行/home/user/www/my-app-laravel/bootstrap/compiled.php

我做错了什么?使用自己的服务的常用方法是什么?我不想把所有逻辑放在控制器中......

1 个答案:

答案 0 :(得分:1)

您遗失的两件主要事情:

  1. ServiceProvider和您的班级之间存在差异。 Laravel中的服务提供商告诉Laravel在哪里寻找服务,但它不包含服务逻辑本身。所以DirectionsSearchService不应该同时存在,imho。
  2. 您需要使用composer.json注册您的课程,以便自动装带器知道您的课程存在。
  3. 为了简单起见,我将使用Laravel IoC' automatic resolution,而不是现在使用服务提供商。

    应用/库/服务/路线/ DirectionsSearchService.php:

    namespace Services\Directions;
    
    class DirectionsSearchService
    {
        public function search($input = array())
        {
            // Your search logic
        }
    }
    

    您可能会注意到DirectionsSearchService没有扩展任何内容。您的服务变得非常松散。

    在您的 DirectionsAPIController.php 中,您可以:

    class DirectionsAPIController extends BaseController
    {
        protected $directionsSearchService;
    
        public function __construct(Services\Directions\DirectionsSearchService $directionsSearchService)
        {
            $this->directionsSearchService = $directionsSearchService;
        }
    
        public function search()
        {
            return $this->directionsSearchService->search(Input::all());
        }
    }
    

    使用上面的代码,当Laravel尝试__construct()您的控制器时,它会查找Services\Directions\DirectionsSearchService并自动注入控制器。在构造函数中,我们只需将其设置为实例变量,以便search()可以在需要时使用它。

    你缺少的第二件事是用作曲家的自动加载来注册你的课程。通过添加到composer.json的自动加载部分来执行此操作:

    "autoload": {
        "classmap": [
            ... // Laravel's default classmap autoloads
        ],
        "psr-4": {
            "Services\\": "app/libraries/Services"
        }
    }
    

    在对composer.json进行更改后执行composer dump-autoload。你的代码应该再次运行。


    上面的建议也可以通过服务提供商和界面编码更好。它可以更容易地控制注入控制器的内容,因此更容易在模拟中创建和注入以进行测试。

    它涉及更多步骤,因此我在此处未提及,但您可以在Exploring Laravel’s IoC containerLaravel 4 Controller Testing中阅读更多内容。