欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

宁皓网 Laravel 5:路由 有大用

shiping1 的头像
Route 这个词本身是路线或者路径的意思。在程序设计里面 .. 它的名字可以翻译成路由 .. 路由决定了把来访的用户带到哪里去 .. 至于在那些方怎么样去接待用户,为用户提供什么内容,这些一般是应用里的其它的部分提供的功能。

封面摄影:jae youn Ryu

来自 http://ninghao.net/course/3225#info
 

准备
安装与创建 Laravel 5 项目

使用我们在 Web 运行环境这个课程里手工搭建的环境,可以去运行 Laravel 项目。推荐您先看一下这个课程 .. 下面我们一起在这个环境上去创建一个新的 Laravel 项目 ..

Mac 用户可以打开终端 .. Windows 用户可以使用 Powershell .. 在我们的桌面上 .. 有一个 web-stack .. 进入到这个目录的下面 .. 然后启动一下虚拟机 .. vagrant up ... 再连接到这台虚拟机 .. vagrant ssh ..

进来以后,先去创建一个 Laravel 项目 .. 进入到 /vagrant/app .. 这个目录就是我们安装的一些应用 .. Drupal,WordPress ,phpMyAdmin 等等 .. 创建新的 Laravel 项目可以使用 Laravel 这个命令 ..

这里我们可以先去升级一下 Laravel 的安装器 .. composer global update laravel/installer

完成以后再输入一个 laravel new laravel-5 .. 这样会创建一个叫 laravel-5 的项目 ..

再去配置一下这个项目的 NGINX 的虚拟主机 .. 可以复制一个现有的配置文件 .. cp /etc/nginx/conf.d/laravel.conf /etc/nginx/conf.d/laravel-5.conf

这个 laravel.conf 配置文件是我们在搭建环境的时候创建的 .. 具体的方法您可以参考宁皓网的 Web 运行环境这个课程 ...

再去编辑一下这个新复制的配置文件 .. sudo vi ... 修改一下它的 server_name 指令的值 .. web-stack.laravel-5.ninghao.local ..

再改一下根目录的地址 .. /vagrant/app/laravel-5 这个目录下面的 public .. .. 保存一下 .. 让配置生效,再重新加载一下 NGINX .. sudo systemctl reload nginx

我们需要再修改一下自己电脑的 HOSTS 文件, 新建一个标签 .. sudo vi /etc/hosts ..

添加一条新的记录 .. 先是虚拟机的 ip 地址 .. 192.168.33.150 然后是虚拟的一个主机名 .. web-stack.laravel-5.ninghao.local ..再保存一下

回到虚拟机 .. 去给 laravel 创建一个数据库 .. mysql -u root -p .. 登录到 mysql 以后,再用 create database 去创建一个名字是 laravel_5 的数据库 .. 回车执行一下 .. exit 退出 ..

打开浏览器 .. 输入 http://web-stack.laravel-5.ninghao.local .. 打开以后,你会看到 Laravel 的欢迎界面 ...
来自 http://ninghao.net/video/3227#toc


Laravel 项目的基本配置

打开编辑器 ... 这里我用的是 Atom 这个编辑器 .. 打开桌面上的 web-stack .. app 下面的 laravel-5 这个目录 .. 它就是我们在上一个视频里创建的一个新的 Laravel 项目 .. 这个目录跟虚拟机上的 /vagrant/app/laravel-5 是同步的 ..

laravel 项目的相关配置都会放在 config 这个目录的下面 ... 你可以打开这个目录下面的文件 .. 看看里面都有什么样的配置选项可以使用 ...

目录权限

然后我们要检查项目下面的几个目录的权限 ... 回到终端 ... 进入到 Laravel 项目所在的目录 .. 然后查看一下目录下面的东西.. ls -la ..

首先我们要确定这里的 storage 这个目录有可以写入的权限 .. 它是一个存储资源用的目录 .. 比如一些缓存 .. 日志 .. 上传的文件等等 ..

我们的 Web 服务器用的是 NGINX,处理 PHP 请求用的是 PHP-FPM,所以你需要保证运行 PHP-FPM 这个服务的那个用户,对这个目录拥有可以写入的权限 ...

另外我们还要保证, bootstrap 这个目录下面的 cache 这个目录,也可以写入东西 ... 在我们的环境里,运行 PHP-FPM 的用户是 vagrant,storage 还有 bootstrap 下面的 cache 这两个目录的拥有者也是 vagrant ,所以不需要担心这个权限的问题。

Application Key

在使用 composer 或者 laravel 的安装器创建的 Laravel 项目,会自动生成一个应用的 key .. 而且这个 key 已经放到了项目根目录下的 .env 这个文件里面了 .. 打开这个文件 .. 就是这个 APP_KEY .. 如果没有这个 KEY ,可能会有一些安全问题 .. 用户的会话,还有一些其它的加密数据会用到它 ..

我们也可以手工去生成这个 APP KEY .. 可以使用 php artisan key:generate .. 执行以后 .. 会生成新的 app key .. 并且会自动把它放到 .env 文件里的 APP_KEY 的后面 ..

额外配置

Laravel 不需要太多的配置就可以立即去开发 .. 有些常用的配置我们也可以先去修改一下 .. 打开 config 下面的 app.php .. 应用的常用配置会在这个文件里面 .. 先找到 url 这个选项 .. 这里的地址是用在控制台上的 .. 使用 arisan 命令生成地址的时候,需要用到它 .. 打开这个应用首页的地址是 web-stack.laravel-5.ninghao.local ..

timezone 是应用使用的时区 .. 默认是 UTC .. 这里把它改成 Asia/Shanghai

locale 是应用使用的默认的本地化语言 .. 这里是 en ,我们可以换成 zh .. 表示中文 .. 另外还有很多其它的配置选项 .. 我们以后用的时候再去配置一下 .. 先保存一下这个文件 ..

https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes

来自 http://ninghao.net/video/3228#info

 
为 Atom 安装 Laravel 代码片断插件

我们可以给编辑器安装一个跟 Laravel 相关的代码片断插件 .. 这样在平时编写应用的时候,可以少写很多代码 .. 这里我用的是 Atom 编辑器 .. 打开 设置 .. command + ,

install .. 搜索一下 laravel .. 找到这个描述是 add laravel snippets 的包 .. 点击 安装 ... 完成以后重新启动一下 Atom 编辑器 ...

再打开设置 ... 打开 package .. 搜索一下刚才安装的 laravel ... 打开它 .. 在 Snippets 这个区域的下面,你可以看到这个插件里面定义的跟 Laravel 相关的代码片断 ...

来自 http://ninghao.net/video/3229#info

路由 - Routing
路由的介绍

Route 这个词本身是路线或者路径的意思。在程序设计里面 .. 它的名字可以翻译成路由 .. 路由决定了把来访的用户带到哪里去 .. 至于在那些方怎么样去接待用户,为用户提供什么内容,这些一般是应用里的其它的部分提供的功能。

在路由里面可以定义一些地址,这些地址就是我们的网站或应用跟用户之间的一个接口 .. 用户在请求这些地址的时候,网站可以按照我们的设计为用户做出不同的响应 ..

比如你可以定义一个地址是 user/profile 的路由 .. 这个地址可以为登录的用户返回他们的用户资料 ... 用户在访问这个地址的时候,在这个路由指定的方法里面,可以先验证一下用户是不是已经登录了.. 如果没有,就把用户重定向到一个登录的地方 .. 如果登录了 .. 就给用户返回他们的个人资料 ...

处理这些不同行为的逻辑都是我们自己来设计的 ... 简单的请求,可以直接在路由的一个函数参数里面去处理 ... 如果比较复杂 .. 我们可以把请求交给应用里的控制器去处理。

来自 http://ninghao.net/video/3231#info

 
基本路由:get

打开 app/Http .. 在应用里的一般的路由我们都会放到这个 routes.php 里面 .. 打开这个文件 .. 默认这里定义好了一个 get 类型的路由 .. 它的地址是一个斜线 .. 表示网站的根或者首页 .. 这个路由返回了一个视图 .. 名字是 welcome .. 在以后我们会单独再去介绍视图 ..

下面我们再去定义一个 get 类型的路由,它匹配的就是使用 HTTP 的 get 方法请求的地址 .. 使用 Route 的 get 方法(#ro:g) .. 第一个参数是这个路由的地址 ..... 比如我们叫它 movie ... 第二个参数可以是一个匿名函数 .. 这里面是这个路由要做的事情 ..

我们先简单的返回一个字符串 .. return '电影列表' .. 这个路由的意思就是,访问应用的 movie 这个地址的时候,会返回一个电影列表 .. 打开浏览器 .. 输入网站的地址 .. 后面加上一个 movie .. 这里会显示一个 电影列表 .. 就是 movie 这个路由给我们返回的东西 ..

在浏览器上直接打开这个地址用的就是 HTTP 的 get 方法 ..

来自 http://ninghao.net/video/3232#info

暂时关闭 CSRF 验证

定义的路由可以匹配不同的 HTTP 方法 .. 打开 POSTMAN .. 在这里输入之前定义的 movie 这个路由的地址 .. 注意这里用的是 get 方法 .. 点击发送 .. 下面会返显示返回的内容 .. 电影列表 .. 这次我们把请求的方法换成 post ... 再点一下发送 ..

这次返回的是一个错误的提示页面 .. TokenMismatchException ...

这其实是一个 csrf,身份欺诈验证失败的一个错误 .. 我们可以先暂时关掉这个 csrf 验证 .. 打开 app/Http/Middleware .. 打开 VerifyCsrfToken.php ..

在这个 $except 里面我们可以列出不要求验证 CSRF 的地址 .. 这里我们先用一个 * 号 .. 以后再介绍中间件的时候再回过来看一下 .. 保存 ..

回到 Postman .. 再发送一下这个请求 ... 这次返回的是一个 MethodNotAllowedHttpException .. 意思是我们请求的这个地址,不支持使用当前选择的 HTTP 方法,也就是 post 这种方法 ...

下面我们再去定义支持其它 HTTP 方法的路由。
来自 http://ninghao.net/video/3233#info

基本路由:post, put, delete

访问地址返回内容,可以使用 HTTP 的 GET 方法 .. 定义 get 类型的路由可以去处理这样的请求 .. 用户如果想提交新的内容到网站上 .. 我们可以去定义 post 类型的路由去处理发布新内容的请求 .. 修改内容可以使用 put 方法 .. 删除内容用的是 delete 方法 ..

我们先去定义一个 post 类型的路由 .. 使用 Route 的 post 方法 .. 第一个参数是路由的地址 .. 设置成 movie .. 第二个参数就是处理这个请求要执行的动作 .. 这里用了一个匿名函数 .. 我们还是简单的返回点文字 ... return '发布电影...';

保存 .. 回到 postman .. 请求一下刚才定义的路由地址 .. movie .. 方法选择 post .. 然后点击发送 .. 这里返回的就是 发布电影 ...

我们可以提供给用户一个表单 .. 用户在里面填写好内容 .. 可以使用 post 方法,把这些表单里的内容发送给我们的应用 .. 在我们的网站应用里,可以接收到这些内容,然后把它们放到数据库里存储一下 ..

另外你还可以去定义 put 或者 delete 类型的路由 .. 用的就是 Route 的 put 还有 delete 方法 .. 先添加一个 put 类型的路由 .. 使用 Route 的 put .. 设置一下路由的地址 .. movie .. 使用 put 方法请求这个 movie 地址的时候,返回一个 '修改电影...'

再添加一个 delete 方法的路由 .. 使用 Route 的 delete 方法 .. 地址也是 movie .. 使用 delete 方法请求 movie .. 返回一个 '删除电影...' 保存 .. 再回到 postman ...

请求的地址设置成 movie .. 先用 get 方法试一下 .. 发送请求 .. 返回的结果就是 电影列表 .. 再换成 post .. 再发送一下 .. 返回的是 发布电影 ... 再试试用 put 方法 .. 点击 发送 .. 这次返回的是 修改电影 .. 最后再试一下 delete .. 点击发送 .. 返回的是我们定义的 delete 类型的路由里面要做的事情 .. 就是返回 删除电影 这几个字儿 ..

来自 http://ninghao.net/video/3234#info

 
定义多方法路由

我们可以定义一个路由让它支持多种 HTTP 的方法 .. 用的是 Route 的 match .. 或者也可以让路由支持所有的 HTTP 方法 .. 可以使用 any ... 先试一下 match ..

使用 Route 的 match .. 它的第一个参数可以是一个数组 .. 里面是这个路由支持的方法 .. 用一个 get .. 再输入一个 post .. 第二个参数是路由的地址 .. movie ... 然后是一个匿名函数 .. 里面是这个路由处理请求的行为 .. 先简单的返回一串字符 .. return '电影';

保存 .. 打开 postman .. 请求的地址是 movie .. 现在用的是 get 方法 .. 发送请求 .. 会返回 电影 这两个字 .. 再试一下用 post 方法请求这个地址 .. 同样会返回一个电影 ... 再把请求的方法换成 put ... 这回就会报错了 .. 因为现在这个路由只支持 get 还有 post 这两种方法 ..

如果想让路由支持所有的 http 方法,可以使用 any 去定义路由 .. 回到编辑器 .. 注释掉这个路由 .. 再用 Route 的 any .. 方法去定义一个路由 .. 地址是 movie ... 要做的事就是返回 电影 这两个字儿 ..

保存 .. 再去试一下 .. 请求的地址仍然是 movie .. 先用 put 方法试一下 .. 返回的是电影 .. 再试一下 delete .. 同样可以返回 电影 这两个字儿 .. 因为现在这个路由用的是 any 方法定义的,所以它支持所有的 HTTP 方法 ...

来自 http://ninghao.net/video/3235#info

Route Parameters
路由中的参数 - Route Parameters

前面定义了一些静态的路由,也就是路由的地址一直就是我们定义的那个,比如 movie 就是 movie 这个地址 .. 在路由的地址里面我们可以使用一些参数 ..

使用 Route 的 get 方法 .. 添一个路由 ... 地址是 movie/ ,然后可以加上一个电影 id 的参数 .. 地址里的参数需要使用一组大括号 .. 里面是参数的名字 .. 比如 movie_id ..

路由地址里面的参数的值会传递给后面的这个要匿名函数里面,给这个函数添加一个参数 ... 这里也叫它 $movie_id .. 它里面再用一个 return .. 返回 .. 电影这两个字儿 .. 后面再加上 $movie_id 这个参数的值 ... 也就是用户在访问 movie/1 的时候,这个 movie_id 参数的值就会是 1 ..

这样在处理请求的这个函数里面,我们可以根据用户访问的电影的 id 号,从数据库里面提取出对应的电影内容 ...

保存 .. 再去试一下 .. 这回请求的地址可以是 movie/ 后面加上一个 id 号 ... 输入一个 1 .. 回车执行一下 .. 返回的结果就是 电影 ... 后面加上路由地址里的 movie_id 这个参数的值 ..

再试一下 movie/3 .. 返回的就是 电影:3 ...

来自 http://ninghao.net/video/3237#info

路由中的多参数与可选参数

路由地址里面可以包含多个参数 .. 再去定义一个路由 .. 复制一下前面定义的这个带参数的路由 .. 在这个路由的地址里面,再加上一个 review .. 表示电影的评论 .. 斜线 .. 后面再加上一个表示影评 id 的一个参数 .. 名字是 review_id ..

然后在后面的这个函数里面,可以再给它添加一个参数 .. 名字是 $review_id .. 在返回的东西里面,再添加点东西 .. 里面的影评 .. 后面加上 $review_id 这个参数的值 .. 保存 .. 再试一下这个路由(#浏览器) ..

请求的地址是 movie/ 电影的 id 号,3 .. 斜线 .. review .. 斜线 .. 后面是影评的 id 号 .. 1 .. 执行一下 .. 结果就是电影 3 里面的影评 1 ..

去掉这个 review_id 参数的值再试一下 .. 这次会报一个错 ... 提示没找到页面 .. 如果路由地址里的参数是可选的 .. 需要在参数名的后面加上一个 ? 号 .. 回到编辑器 .. 这里我让 review_id 这个参数变成一个可选的参数 .. 在它后面加上一个 ? 号 ..

然后在后面的这个匿名函数里面的也需要再设置一下 .. 给这个 $review_id 参数一个默认的值 .. 让它等于 null .. 保存 .. 再访问一下这个地址 ..

这回没报错 .. 因为 review_id 这个参数的值是可选的 .. 再给它指定一个值 .. 在返回的结果里会包含这个参数的值 ...
来自 http://ninghao.net/video/3238#info

限制路由中的参数值的类型

先输入一个 movie/369 ... 这个地址里的 369 就是路由里的 movie_id 这个参数的值 .. 再试一下,把这个数字换成一个字符串 .. fargo .. 在返回的结果里同样会包含这个字符串类型的参数的值 ...

在路由里我们可以使用正则表示式来限制参数的值的类型 .. 回到编辑器,找到这个路由 .. 在它的后面用一个小箭头符号 ... 再加上一个 where 方法 .. 它的第一个参数是要限制的参数 .. 输入一个 movie_id ..

第二个参数是一个正则表达式 ..

比如我想让 movie_id 的值只能是字母 .. 可以这样 .. 用一组方括号 .. A-Z .. a-z .. 方括号外面再加上一个加号 .. 表示可以是任意数量的字符 .. 保存 .. 回到浏览器 .. 刷新一下 ..

现在 movie_id 这个参数的值是一个字符串 .. 没有问题 ... 再把它换成一个数字 ... 369 .. 这回就报错了 .. 因为我们限制了 movie_id 参数的值只能是字母 ..

回到编辑器 .. 如果你想让它只能是数字的话 .. 可以用一个 0-9 .. 再修改一下,下面这个路由 .. 在这个路由里有两个参数.. 先用一个 -> where .. 限制多个参数 .. 可以使用一个数组 .. 数组里的项目先是参数的名字 .. 用一个 movie_id .. 大箭头 .. 然后是正则表达式,也就是参数的值必须要匹配的一种模式 .. 设置成 [0-9]+ .. 逗号分隔一下 .. 再设置一下 review_id 这个参数 .. 我们也让它只能是数字 .. [0-9]+ ..

保存 ... movie/369/review/hello .. 报错了.. 因为 review_id 这个参数的值只能是数字 .. 换成数字 3 .. 这次可以正常返回内容 .. 因为路由里的参数的值的类型都符合我们的设置 ...

来自 http://ninghao.net/video/3239#info

在全局限制路由参数值的类型

您可能希望路由里面的参数都是一种类型的,比如都是数字,或者都是字母,这样我们就不需要单独去限制每一个路由参数的值,可以在全局范围配置一下参数的值的类型 ..

先去掉单独为路由参数限制类型的代码 .. 就是这个 ->where ...

保存一下 .. 然后在 app/Providers 下面 ... 找到 RouteServiceProvider.php .

在这个 RouteServiceProvider 类的 boot 方法里面 .. 可以去设置一下路由参数的类型 .. 使用 $router 的 pattern 方法 .. 这个方法有两个参数 .. 第一个参数是要设置的参数 .. 先设置一下 movie_id 这个参数 .. 第二个参数是它的值的类型 .. 我们让这个 movie_id 只能是数字 .. 用一个 [0-9]+

再用一下这个方法 .. 设置一下其它的参数的类型 .. 把这个 movie_id 换成 review_id .. 保存 ... 到浏览器上试一下 .. movie/1/review/1 .. 没有问题 .. 因为 movie_id 还有 review_id 的参数的值都是数字 ..

这次把 movie_id 的值换成一串字符 .. up ... 这回就不行了 .. 因为我们在全局范围已经限制了 movie_id 这个参数的值的类型只能是数字 ...

来自 http://ninghao.net/video/3240#info

命名路由与路由群组
有名字的路由 - Named Routes

给定义的路由起个名字,这样在我们的应用里就可以使用这个名字来表示定义的这个路由了。比如在使用重定向的时候,可以用路由的名字来表示想要重定向到的那个地址 ...

先去定义一个基本的 get 类型的路由 .. 地址是 user/login .. 命名这个路由可以这样 .. 让路由方法的第二个参数变成一个数组 .. 这个数组里的第二个项目是这个函数 .. 第一个项目可以是这个路由的名字 ... 用一个 as => 然后就是这个路由的名字 .. 比如我们叫它 login ..

访问这个路由的地址 .. 返回几个文字 ... return '用户登录';

下面我们再去定义一个路由 ... 类型也是 get .. 地址是 user/profile .. 它可以是显示用户资料用的, 在这个路由里,如果我们想把用户重定向到上面的这个 user/login 这个地址 .. 可以使用这个路由的名字来表示 ..

用一个 return .. 重定向可以使用 redirect .. 使用它的 route 方法 .. 在这个方法里可以指定一下想要重定向到的那个路由的名字 .. 这里就是 login .. 这个 route 方法可以根据我们提供给它的路由的名字生成合适的地址 ...

保存 .. 到浏览器上去试一下 ... 打开 user/profile 这个地址 .. 回车 .. 这样会把用户重定向到 user/login 这个地址上来 .. 因为我们在 user/profile 这个路由里面,使用 redirect 的 route 方法, 把用户带到路由名字是 login 的这个地址上来 ...

再回到编辑器 .. 我们也可以使用 name 方法去给路由起名字 .. 先注释掉这个 login 路由 .. 再去定义一个 .. 地址仍然是 user/login .. 返回 用户登录 ..

在这个路由方法的后面,再用一个 name 方法 .. 它的第一个参数就是我们给路由起的名字 ... 设置成 login .. 保存 ..

再回到浏览器... 打开 user/profile ... 同样可以重定向到这个 login 路由上来 ...

来自 http://ninghao.net/video/3242#info

路由群组 - Route Groups

如果你定义的路由有一些共同的地方,比如使用相同的前缀,中间件,或者命名空间。我们可以把这些路由组织到一块儿 .. 这就是路由的群组。

定义路由群组可以使用 Route 的 group 方法 .. (#ro:gr) .. 它的第一个参数是一些属性 .. 第二个参数用了一个匿名函数 .. 里面包含的就是定义的路由 ..

比如我想让它里面的路由使用同样的前缀 .. 设置一下它的属性参数 .. 是一个数组 .. 然后先是要设置的属性的名字 .. 表示前缀的属性是 prefix .. 再用一个大箭头 .. 接着是对应的值 .. 比如这个群组里的路由是为网站的管理界面准备的 .. 这些路由里的地址都有一个 admin 前缀 .. 这里我们就可以把 prefix 这个属性的值设置成 admin ..

再去添加两个路由 .. 使用 Route 的 get 方法 .. 地址是 user .. 返回一个 管理用户 .. 再添加一个路由 .. 地址是 content .. 返回的是 管理内容 ..

因为这里我们用的是一个路由群组 .. 这个路由群组用了一个前缀是 admin ,所以访问它里面的路由的时候,需要加上这个 admin 前缀 .. 保存 .. 回到浏览器 .. 输入一个 admin/user .. 返回的就是 管理用户 .. 再试一下 admin/content .. 返回的是管理内容 ..

来自 http://ninghao.net/video/3243#info

 


普通分类: