资讯专栏INFORMATION COLUMN

Lumen 初体验

Leck1e / 1414人阅读

摘要:介绍为速度而生的框架。是官方给出的例子,直接拷贝命名为。一般来说,我们应该避免使用末尾带斜杠的。因为它如果找不到文件,就会自动在末尾加个斜杠,尝试寻找目录下的文件等等,具体是在中配置。方案修改修改的配置文件,将指向重启。

介绍

Lumen:“为速度而生的 Laravel 框架”。

Lumen 是 Laravel 的作者(Taylor Otwell)的又一力作。简单、快速、优雅的它的特点,适合用于构建微服务架构和 API 应用。
官网:http://lumen.laravel.com
介绍:https://phphub.org/topics/701
中文文档:http://lumen.laravel-china.org/docs

安装

使用 composer 安装:

</>复制代码

  1. bashcomposer create-project laravel/lumen --prefer-dist
配置

Lumen 默认使用 .env 作为配置文件。.env.example 是官方给出的例子,直接拷贝命名为 .env

</>复制代码

  1. bashcd lumen
  2. cp .env.example .env
调试模式

修改 .env 文件:

</>复制代码

  1. bashAPP_DEBUG=true

如果发现还是没有效果,再修改 lumen/bootstrap/app.php 文件,将 Dotenv::load 的注释移除掉。

疑问 1.为什么提示:not be found

访问:http://127.0.0.1/lumen/public/

显示:

</>复制代码

  1. bashSorry, the page you are looking for could not be found.
  2. NotFoundHttpException in Application.php line 1121:
  3. in Application.php line 1121
  4. at Application->handleDispatcherResponse(array("0")) in Application.php line 1091
  5. at Application->dispatch(null) in Application.php line 1026
  6. at Application->run() in index.php line 28

查看路由文件 lumen/app/Http/routes.php

</>复制代码

  1. php$app->get("/", function() use ($app) {
  2. return $app->welcome();
  3. });

感觉没有问题啊,和在 Laravel 中差不多的方式,那是哪里出了问题了?好的,先不管,尝试自己新定义一条路由规则试试看:

</>复制代码

  1. php$app->get("/test", function() use ($app) {
  2. return $app->welcome();
  3. });

再访问:http://127.0.0.1/lumen/public/test

结果和刚才一样。

2.为什么会跳转

再尝试访问一下:http://127.0.0.1/lumen/public/test/
结果跳转到:http://127.0.0.1/test

解惑

我先来解释一下第 2 个问题,因为这是一个很多 Laravel 新手也经常问的问题。

原因何在?请看 lumen/public/.htaccess 文件:

</>复制代码

  1. bashRewriteRule ^(.*)/$ /$1 [L,R=301]

这是一条 Apache 路由重写规则(mod_rewrite 开启的情况下才有效),当请求的 URI 带有 /,就会匹配出 $1, 永久重定向(HTTP 状态码是 301)到根目录下的 $1。上面的例子中,匹配到 test(就是$1),就跳转至 /test 了。

如何来规避上面这个问题?注释这条 RewriteRule 吗?不是的。一般来说,我们应该避免使用末尾带斜杠的 URI。为什么 URI 末尾不应该带有斜杠呢?从语义是来说, test/ 表示目录,test 表示资源。还有,如果在 lumen/public 目录下真的有一个 test 目录,那么访问 http://127.0.0.1/lumen/public/test/,就会进入到 test 目录下面来,这不是我们想要的结果。(其实如果真的存在 test 目录并且不存在文件 test,那么,URI 末尾有没有斜杠都会进入到 test 目录中来,这是 Apache 决定的。因为它如果找不到文件,就会自动在末尾加个斜杠,尝试寻找目录下的 index.html 文件等等,具体是在 httpd.conf 中配置 DirectoryIndex。好吧,扯得太远了,拽回来)
总之,我还是建议 URI 末尾不要带 /,如果你非不听,那就注释上面那句 RewriteRule 吧,这样就不会重定向了。

关于第 1 个问题,我们也来分析一下发生的原因,这样才能对症下药。
根据错误提示,定位到文件 lumen/vendor/laravel/lumen-framework/src/Application.php 中:

</>复制代码

  1. php /**
  2. * Dispatch the incoming request.
  3. *
  4. * @param SymfonyRequest|null $request
  5. * @return Response
  6. */
  7. public function dispatch($request = null)
  8. {
  9. if ($request) {
  10. $this->instance("IlluminateHttpRequest", $request);
  11. $this->ranServiceBinders["registerRequestBindings"] = true;
  12. $method = $request->getMethod();
  13. $pathInfo = $request->getPathInfo();
  14. } else {
  15. $method = $this->getMethod();
  16. $pathInfo = $this->getPathInfo();
  17. }
  18. try {
  19. if (isset($this->routes[$method.$pathInfo])) {
  20. return $this->handleFoundRoute([true, $this->routes[$method.$pathInfo]["action"], []]);
  21. }
  22. return $this->handleDispatcherResponse(
  23. $this->createDispatcher()->dispatch($method, $pathInfo)
  24. );
  25. } catch (Exception $e) {
  26. return $this->sendExceptionToHandler($e);
  27. }
  28. }

匹配不到 route 的原因就在以上代码中。假设访问:http://127.0.0.1/lumen/public,那么 :

</>复制代码

  1. phpvar_dump($method); // string(3) "GET"
  2. var_dump($pathInfo); // string(14) "/lumen/public/"

根据 lumen/app/Http/routes.php 中的定义,生成 $this->routes

</>复制代码

  1. phpvar_dump(array_keys($this->routes)); // array(2) { [0]=> string(4) "GET/" [1]=> string(8) "GET/test" }

由上可知, isset($this->routes[$method.$pathInfo]) 的结果就是 false,所以提示 not be found 了。
既然已经知道了原因,那问题就好解决了。解决的前提是不要改动框架的源代码,不然日后升级框架会多么蛋疼,你都把框架代码都修改,万一出了问题你咋办?你自己拆手机,官方是不保修的哦!当然,如果你是框架开发组的,你提交代码能被大家接受并被官方合并到主干代码中了,那你就改吧。

方案1:修改 DocumentRoot

修改 Apache 的配置文件 httpd.conf,将 DocumentRoot 指向 lumen/public

</>复制代码

  1. bashDocumentRoot "/sites/lumen/public"

重启 Apache。

但是,如果我还有其他站点也在这个 Apache 下面,改 DocumentRoot 就会导致其他的站点不能访问了。怎么办?请看方案 2

方案2:配置 Apache 虚拟主机

修改 httpd.conf,将下面这行的注释移除:

</>复制代码

  1. bashInclude etc/extra/httpd-vhosts.conf

修改 httpd-vhosts.conf

</>复制代码

  1. bash
  2. DocumentRoot "/sites"
  3. ServerName 127.0.0.1
  4. DocumentRoot "/sites/lumen/public"
  5. ServerName lumen.app

重启 Apache。

修改主机的 etc/hosts,添加一行:

</>复制代码

  1. bash127.0.0.1 lumen.app

其中 127.0.0.1 应该换成你 lumen 应用存放的机器的 ip。

OK,这样就可以通过访问 http://lumen.app 来访问该 lumen 站点,通过 http://127.0.0.1 来访问其他站点。

但是,你压根不能修改 Apache 的配置,怎么办?请看方案 3

方案3.修改路由规则中的路径

改不了配置,就改代码喽(再强调一下,不是修改框架的源代码)。

修改路由文件 lumen/app/Http/routes.php

</>复制代码

  1. php
    define("ROUTE_BASE", "lumen/public");
  2. $app->get(ROUTE_BASE . "/index", function() use ($app) {
  3. return $app->welcome();
  4. });
  5. $app->get(ROUTE_BASE . "/test", function() use ($app) {
  6. return $app->welcome();
  7. });

这样,如果以后有变化的话,你只需要修改 define("ROUTE_BASE", "lumen/public/");就可以了(当然,把这个写到应用配置项中是最合适的,部署时修改配置就可以了)。

至于想以 "lumen/public/" 作为首页 URI 显然是不可以的,建议使用 "lumen/pulbic/index" 作为首页。如同上面代码定义的路由规则那样。

因为,无论你在路由规则的字符串末尾加了多少个斜杠, $this->routes 的键是不会带有斜杠的,最终还是不能匹配的。原因在框架源代码中 lumen/vendor/laravel/lumen-framework/src/Application.php

</>复制代码

  1. php /**
  2. * Add a route to the collection.
  3. *
  4. * @param string $method
  5. * @param string $uri
  6. * @param mixed $action
  7. */
  8. protected function addRoute($method, $uri, $action)
  9. {
  10. $action = $this->parseAction($action);
  11. $uri = $uri === "/" ? $uri : "/".trim($uri, "/");
  12. if (isset($action["as"])) {
  13. $this->namedRoutes[$action["as"]] = $uri;
  14. }
  15. if (isset($this->groupAttributes)) {
  16. if (isset($this->groupAttributes["prefix"])) {
  17. $uri = rtrim("/".trim($this->groupAttributes["prefix"], "/").$uri, "/");
  18. }
  19. $action = $this->mergeGroupAttributes($action);
  20. }
  21. $this->routes[$method.$uri] = ["method" => $method, "uri" => $uri, "action" => $action];
  22. }

对,就是它:$uri = $uri === "/" ? $uri : "/".trim($uri, "/");
所有,URI 末尾还是不带斜杠的好。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30236.html

相关文章

  • Lumen 体验(二)

    摘要:的现状目前是版本,是基于开发。入口文件启动文件和配置文件框架的入口文件是。在路由中指定控制器类必须写全命名空间,不然会提示找不到类。目前支持四种数据库系统以及。使用时发生错误,因为在文件中,的默认驱动是。 最近使用 Lumen 做了 2 个业余项目,特此记录和分享一下。 Lumen 的介绍 在使用一项新的技术时,了解其应用场景是首要的事情。 Lumen 的口号:为速度而生的 La...

    Cheriselalala 评论0 收藏0
  • Lumen---为速度而生的 Laravel 框架

    摘要:什么是官网是一个由组件搭建而成的微框架是当前最快的框架之一在什么时候使用专为微服务或者设计举个例子如果你的应用里面有部分业务逻辑的请求频率比较高就可以单独把这部分业务逻辑拿出来使用来构建一个小因为是对优化了框架的加载机制所以对资源的要求少很 什么是 Lumen?官网 lumen 是一个由 Laravel 组件搭建而成的微框架,是当前最快的 PHP 框架之一! 在什么时候使用 Lume...

    104828720 评论0 收藏0
  • 学习 Lumen 用户认证 (一)

    摘要:在开发中,用户认证是核心,是数据是否有保障的前提,目前主要有两种常用方式进行用户认证和。附是为了在网络应用环境间传递声明而执行的一种基于的开放标准。 好久没写 PHP 代码了,尤其是 Lumen,我是 Lumen 的忠实用户,自从面世开始,我就将 Lumen 作为我 API 的主要框架使用。 但说到 API,不得不说的一个概念:「前后端分离」,现在越来越多的团队都采用前后端分离,彻底解...

    wangzy2019 评论0 收藏0
  • 如何在Lumen中使用Elasticsearch

    摘要:之前受到这篇为你的站点插上的翅膀的启发就尝试在中引入,并完成中文索引。关于中文索引谷歌上关于中文搜索的文章有很多,例如这篇。中文索引中涉及的内容比较多,下次再用一个篇幅来分析。 如何在Lumen中使用Elasticsearch 前言 Lumen是基于Laravel核心组件的微框架,随着Laravel5的发布,目前版本也已经到5了。之前受到这篇为你的站点插上ElasticSearch...

    jubincn 评论0 收藏0

发表评论

0条评论

Leck1e

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<