【发布时间】:2015-04-24 02:53:04
【问题描述】:
简介
我以前从未使用过框架(Zend、CakePHP 等),最后决定坐下来学习一个。我从 Laravel 开始,因为代码看起来很漂亮,并且与我尝试安装的其他一些框架不同,“Hello, World!”示例在第一次尝试时有效。
目标
目前,我希望我的应用做一些非常简单的事情:
用户提交请求格式为:
GET /dist/lat,lng应用使用远程IP地址和MaxMind来判断
$latitude1和$longitude1此请求路径被解析为
$latitude2和$longitude2使用这两个位置,我们计算它们之间的距离。为此,我使用Rafael Fragoso's WorldDistance PHP class
由于我打算在以后的项目中重复使用这个函数,所以将所有代码都扔到/app 目录中似乎不太合适。该应用程序的两个可重用部分是:
- 连接 MaxMind 并返回纬度和经度的服务提供者
- 获取地球上两个点并返回距离的服务提供者
如果我正确构建了外观,那么我的 routes.php 文件不会是闭包中的一堆闭包,我可以简单地写:
Route::get('dist/{input}', function($input){
$input = explode( "," , $input );
return Distance::getDistance( GeoIP::getLocation(), $input );
});
我尝试过的
初步尝试
对于第一个服务提供商,我找到了Daniel Stainback's Laravel 5 GeoIP service provider。它没有像应有的那样轻松安装(我必须手动将geoip.php 复制到/config 目录,手动更新/config/app.php,然后运行composer update 和php artisan optimize)但是它起作用了:A request到GET /test返回了我所有的信息。
对于第二个服务提供商,我首先尝试模仿 GeoIP 服务提供商的目录结构和文件命名约定。我想如果我有相同的命名约定,自动加载器将能够找到我的类。于是我创建了/vendor/stevendesu/worlddistance/src/Stevendesu/WorldDistance\WorldDistanceServiceProvider.php:
<?php namespace Stevendesu\WorldDistance;
use Illuminate\Support\ServiceProvider;
class WorldDistanceServiceProvider extends ServiceProvider {
protected $defer = false;
public function register()
{
// Register providers.
$this->app['distance'] = $this->app->share(function($app)
{
return new WorldDistance();
});
}
public function provides()
{
return ['distance'];
}
}
然后我将此添加到我的/config/app.php:
'Stevendesu\WorldDistance\WorldDistanceServiceProvider',
此操作失败并出现致命错误:
FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found
使用工作台
由于这完全失败了,我认为必须有其他一些文件依赖项:可能没有 composer.json 或没有 README 它放弃了。我不知道。所以我开始研究包的创建。几次谷歌搜索“create package laravel 5”被证明是徒劳的。要么:
- 他们使用的是 Laravel 4.2,在这种情况下,建议是“运行 php artisan workbench vendor/package --resources”
或者
- 他们使用的是 Laravel 5,在这种情况下 the docs were completely useless
官方 Laravel 5 文档为您提供了大量示例代码,例如:
你需要做的就是告诉 Laravel 给定命名空间的视图所在的位置。例如,如果您的包裹名为“courier”,您可以在服务提供商的引导方法中添加以下内容:
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}
这假设您有一个服务提供商可以在其中放置引导方法
文档中没有任何内容说明如何创建服务提供者以使其实际由 Laravel 加载。
我还发现 several different resources 所有这些都假设您有一个存储库并且您只想将它包含在您的应用程序中,或者假设您有“工作台”。完全从头开始创建一个新包没什么。
PHP Artisan 甚至没有“workbench”命令,/config 中也没有“workbench.php”文件,所以我发现的任何与 workbench 相关的东西都是毫无价值的。我开始对 Workbench 进行一些研究,并在 StackOverflow 上找到了 several different questions。
经过很长时间和一些实验,我设法将laravel/workbench 放入了我的composer.json,composer update,composer install,手动构建了一个workbench.php 配置文件,最后使用PHP Artisan Workbench 命令制作了一个新包:
php artisan workbench Stevendesu/WorldDistance --resources
这创建了一个目录:/workbench/stevendesu/world-distance,其中包含许多子目录和一个文件:/workbench/stevendesu/world-distance/src/Stevendesu/WorldDistance/WorldDistanceServiceProvider.php
这个服务提供者类与我之前创建的文件基本相同,只是它位于/workbench 目录而不是/vendor 目录中。我尝试重新加载页面,但仍然出现致命错误:
FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found
我也试过php artisan vendor:publish。我真的不知道这个命令是做什么的,并且描述没有帮助,所以也许它会有所帮助?没有。
问题
我如何创建一个新的服务提供者作为一个包,以便在未来的项目中我可以简单地包含这个包并拥有所有相同的功能?或者更确切地说,我做错了什么导致我创建的包不起作用?
【问题讨论】:
标签: php laravel package composer-php laravel-5