如何不配置 Rewrite Rule 就使用 Laravel?

# 声明
这不是好的设计模式(anti-pattern),万不得已不要模仿。

# 背景
如何让 Laravel 像 WordPress 一样容易安装?

大多数时候,你的客户并非专业人士,有安装 WordPress、Discuz 经验,但不懂 php.ini, nginx.conf 之类的配置。这时候,你把一个 Laravel 安装包给他,最大的一个障碍就是 Laravel 需要配置 Rewrite Rule。这个障碍会直接影响到你软件的销量。

尽管 Apache 不需要配置 Rewrite Rule,但这些用户听说 Nginx 性能比 Apache 好,基本都不约而同安装了 Nginx, .htaccess 大法失效。

# 详细方法
下面专门针对 Laravel 的这个问题提出解决方案。本方案会损失一定的灵活性,但能解决问题,并不牺牲 Laravel 给我们带来的任何优势。例子基于 Laravel 5.2

## 基本思路
绕开 Laravel 的路由模式,回退到类似 ThinkPHP 的 controller / method 模式。

## 代码示例
1. app/Http/routes.php 只写一个路由规则

“`php
<?php
Route::get(‘/’, [‘uses’=>’AppController@index’, ‘as’=>’entry’]);
“`

2. app/Http/Controllers/AppController.php 只写一个方法

“`php
<?php
// 用于摸索将 Laravel 应用于免 Rewrite Rule 环境
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;

class AppController extends Controller
{
function index(Request $request)
{
// 为了漂亮,你也可以把 $callMap 组织到一个独立的文件里面去,类似 routes.php 的效果
$callMap = [
“default” => “App\Http\Controllers\AppController@default”,
“cloud_upgrade” => “App\Http\Controllers\CloudController@upgrade”,
“food_search” => “App\Http\Controllers\FoodController@search”
/* more mappings here */
];

$c = $request->input(‘c’);
if (empty($c) {
$c = “default”;
}
$api = $callMap[$c];

// 例如: App::call(‘App\Http\Controllers\FoodController@index’);
// 就将控制权移交给 FoodController 了
return \App::call($api);
}

function index(Request $request) {
// 404 not found / default page
}

}

“`
用户访问 http://your.site.com/index.php?c=cloud_upgrade&param1=xxx&param2=xxxx 即可。不需要任何 Rewrite Rule 支持。值得一提的是,虽然自己做路由解析,但 callMap 很好滴规避了 Route-To-Hell 问题(https://philsturgeon.uk/php/2013/07/23/beware-the-route-to-evil/ ) ,具备和 Laravel 原生路由差不多效果。当然了,牺牲也是有的,比如根据正则表达式匹配做路由。我个人可以接受,自己在Controller里面解析好了。

3. 其余 Controller 开发方式跟官方方法一致

## 可改进的空间
1. AppController@index() 里加入 middleware 支持。 有人知道怎么做,欢迎在下面留言。
2. 多了一次不必要的 AppController 调用。也许可以通过提供自定义的 Router 来达到相同的目的,并且性能比系统自带的 Router 更好?毕竟我们的 Router 比系统自带的 Router 要简单得多。
3. 系统自带的 Auth 这一套不能用了,还有一些依赖于 Rewrite Rule 的第三方组件不能用了。还没想到好办法。

# 新交付流程
完成上面的工作后,给用户交付软件流程就简单了:
1. 下载安装包,上传到网站根目录
2. 访问 http://www.xxx.com/public/index.php 即可