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

更新 2016-8-23

五楼 @raidou 同学给出了更完美的方案,电梯:

试了一下将route整到url的query https://github.com/weirongxu/laravel-query...

声明

这不是好的设计模式(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
Route::get('/', ['uses'=>'AppController@index', 'as'=>'entry']);
  1. app/Http/Controllers/AppController.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  default(Request $request) {
       // 404 not found / default page
  }

}

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

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

可改进的空间

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

新交付流程

完成上面的工作后,给用户交付软件流程就简单了:

  1. 下载安装包,上传到网站根目录
  2. 访问 http://www.xxx.com/public/index.php 即可
本帖已被设为精华帖!
本帖由 Summer 于 7年前 加精
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 8
Summer

特殊问题特殊处理,不知道其他人有没遇到类似需求,并且是怎么解决的

7年前 评论
TimJuly

写一个 nginx 配置的示例不就完了,一共就一句话就可以实现 rewrite,要想把程序跑起来至少基本的 nginx 配置肯定是会的,加一句话对他来说应该不困难吧,何必给自己找麻烦呢.

location / {
    index index.php;
    try_files $uri $uri/ /index.php?$query_string;
}
7年前 评论

@TimJuly 一句“写好了放在哪”就把我问倒了。不同平台,目录位置千奇百怪。

7年前 评论
TimJuly

@raywill 只会开关机的客户不要也罢,哈哈.

7年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!