在我的应用中,我使用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 docs和some 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
我做错了什么?使用自己的服务的常用方法是什么?我不想把所有逻辑放在控制器中......
答案 0 :(得分:1)
您遗失的两件主要事情:
DirectionsSearchService
不应该同时存在,imho。composer.json
注册您的课程,以便自动装带器知道您的课程存在。为了简单起见,我将使用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 container和Laravel 4 Controller Testing中阅读更多内容。