<article><h1>Laravel HTTP 路由功能</h1><ul><li><a href="#basic-routing">基本路由</a></li><li><a href="#route-parameters">路由参数</a><ul><li><a href="#required-parameters">必选路由参数</a></li><li><a href="#parameters-optional-parameters">可选路由参数</a></li><li><a href="#parameters-regular-expression-constraints">正则表达式约束</a></li></ul></li><li><a href="#named-routes">命名路由</a></li><li><a href="#route-groups">路由组</a><ul><li><a href="#route-group-middleware">中间件</a></li><li><a href="#route-group-namespaces">命名空间</a></li><li><a href="#route-group-sub-domain-routing">子域名路由</a></li><li><a href="#route-group-prefixes">路由前缀</a></li></ul></li><li><a href="#route-model-binding">路由模型绑定</a><ul><li><a href="#implicit-binding">隐式绑定</a></li><li><a href="#explicit-binding">显式绑定</a></li></ul></li><li><a href="#form-method-spoofing">表单方法伪造</a></li><li><a href="#accessing-the-current-route">获取当前路由信息</a></li></ul><p><a name="basic-routing"></a></p><h2><a href="#basic-routing">基本路由</a></h2><p>构建最基本的路由只需要一个 URI 与一个 <code class=" language-php">闭包</code>,这里提供了一个非常简单优雅的定义路由的方法:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'foo'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token string">'Hello World'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h4>默认路由文件</h4><p>所有的 Laravel 路由都在 <code class=" language-php">routes</code> 目录中的路由文件中定义,这些文件都由框架自动加载。在 <code class=" language-php">routes<span class="token operator">/</span>web<span class="token punctuation">.</span>php</code> 文件中定义你的 web 页面路由。这些路由都会应用 <code class=" language-php">web</code> 中间件组,其提供了诸如 <code class=" language-php">Session</code> 和 <code class=" language-php"><span class="token constant">CSRF</span></code> 保护等特性。定义在 <code class=" language-php">routes<span class="token operator">/</span>api<span class="token punctuation">.</span>php</code> 中的路由都是无状态的,并且会应用 <code class=" language-php">api</code> 中间件组。</p><p>大多数的应用构建,都是以在 <code class=" language-php">routes<span class="token operator">/</span>web<span class="token punctuation">.</span>php</code> 文件定义路由开始的。</p><h4>可用的路由方法</h4><p>我们可以注册路由来响应所有的 HTTP 操作:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token variable">$uri</span><span class="token punctuation">,</span> <span class="token variable">$callback</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">post<span class="token punctuation">(</span></span><span class="token variable">$uri</span><span class="token punctuation">,</span> <span class="token variable">$callback</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">put<span class="token punctuation">(</span></span><span class="token variable">$uri</span><span class="token punctuation">,</span> <span class="token variable">$callback</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">patch<span class="token punctuation">(</span></span><span class="token variable">$uri</span><span class="token punctuation">,</span> <span class="token variable">$callback</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">delete<span class="token punctuation">(</span></span><span class="token variable">$uri</span><span class="token punctuation">,</span> <span class="token variable">$callback</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">options<span class="token punctuation">(</span></span><span class="token variable">$uri</span><span class="token punctuation">,</span> <span class="token variable">$callback</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>有的时候你可能需要注册一个可响应多个 HTTP 方法的路由,这时你可以使用 <code class=" language-php">match</code> 方法,也可以使用 <code class=" language-php">any</code> 方法注册一个实现响应所有 HTTP 的请求的路由:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">match<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token string">'get'</span><span class="token punctuation">,</span> <span class="token string">'post'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">'/'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">any<span class="token punctuation">(</span></span><span class="token string">'foo'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h4>CSRF 保护</h4><p>任何指向 <code class=" language-php">web</code> 中 <code class=" language-php"><span class="token constant">POST</span></code>, <code class=" language-php"><span class="token constant">PUT</span></code> 或 <code class=" language-php"><span class="token constant">DELETE</span></code> 路由的 HTML 表单请求都应该包含一个 CSRF 令牌,否则,这个请求将会被拒绝。更多的关于 CSRF 的说明在 <a href="/docs/5.4/csrf">CSRF 说明文档</a>:</p><pre class=" language-php"><code class=" language-php"><span class="token markup"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>form</span> <span class="token attr-name">method</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>POST<span class="token punctuation">"</span></span> <span class="token attr-name">action</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>/profile<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></span>
<span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token function">csrf_field<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">}</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token markup"><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>form</span><span class="token punctuation">></span></span></span></code></pre><p><a name="route-parameters"></a></p><h2><a href="#route-parameters">路由参数</a></h2><p><a name="required-parameters"></a></p><h3>必选路由参数</h3><p>当然,有时我们需要在路由中捕获一些 URL 片段。例如,我们需要从 URL 中捕获用户的 ID ,我们可以这样定义路由参数:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'user/{id}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token string">'User '</span><span class="token punctuation">.</span><span class="token variable">$id</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>也可以根据需要在路由中定义多个参数:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'posts/{post}/comments/{comment}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$postId</span><span class="token punctuation">,</span> <span class="token variable">$commentId</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>路由的参数通常都会被放在 <code class=" language-php"><span class="token punctuation">{</span><span class="token punctuation">}</span></code> 内,并且参数名只能为字母,当运行路由时,参数会通过路由闭包来传递。</p><blockquote><p><strong>注意:</strong> 路由参数不能包含 <code class=" language-php"><span class="token operator">-</span></code> 字符。请用下划线 (<code class=" language-php">_</code>) 替换。</p></blockquote><p><a name="parameters-optional-parameters"></a></p><h3>可选路由参数</h3><p>声明路由参数时,如需指定该参数为可选,可以在参数后面加上 <code class=" language-php"><span class="token operator">?</span></code> 来实现,但是相应的变量必须有默认值:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'user/{name?}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$name</span> <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token variable">$name</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'user/{name?}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$name</span> <span class="token operator">=</span> <span class="token string">'John'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token variable">$name</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="parameters-regular-expression-constraints"></a></p><h3>正则表达式约束</h3><p>你可以使用 <code class=" language-php">where</code> 方法来规范你的路由参数格式。<code class=" language-php">where</code> 方法接受参数名称和定义参数约束规则的正则表达式:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'user/{name}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">where<span class="token punctuation">(</span></span><span class="token string">'name'</span><span class="token punctuation">,</span> <span class="token string">'[A-Za-z]+'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'user/{id}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">where<span class="token punctuation">(</span></span><span class="token string">'id'</span><span class="token punctuation">,</span> <span class="token string">'[0-9]+'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'user/{id}/{name}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">,</span> <span class="token variable">$name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">where<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token string">'id'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">'[0-9]+'</span><span class="token punctuation">,</span> <span class="token string">'name'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">'[a-z]+'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="parameters-global-constraints"></a></p><h4>全局约束</h4><p>如果你希望路由参数在全局范围内都遵循一个确定的正则表达式约束,则可以使用 <code class=" language-php">pattern</code> 方法。你应该在 <code class=" language-php">RouteServiceProvider</code> 的 <code class=" language-php">boot</code> 方法里定义这些模式:</p><pre class=" language-php"><code class=" language-php"><span class="token comment" spellcheck="true">/**
* 定义你的路由模型绑定, pattern 过滤器等。
*
* @return void
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">boot<span class="token punctuation">(</span></span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">pattern<span class="token punctuation">(</span></span><span class="token string">'id'</span><span class="token punctuation">,</span> <span class="token string">'[0-9]+'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token scope"><span class="token keyword">parent</span><span class="token punctuation">::</span></span><span class="token function">boot<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre><p>Pattern 一旦被定义,便会自动应用到所有使用该参数名称的路由上:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'user/{id}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // 仅在 {id} 为数字时执行...
</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="named-routes"></a></p><h2><a href="#named-routes">命名路由</a></h2><p>命名路由可以方便的生成 <code class=" language-php"><span class="token constant">URL</span></code> 或者重定向,你可以在定义路由后使用 <code class=" language-php">name</code> 方法实现:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'user/profile'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">name<span class="token punctuation">(</span></span><span class="token string">'profile'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>你还可以为控制器方法指定路由名称:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'user/profile'</span><span class="token punctuation">,</span> <span class="token string">'UserController@showProfile'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">name<span class="token punctuation">(</span></span><span class="token string">'profile'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h4>为命名路由生成 <code class=" language-php"><span class="token constant">URL</span></code></h4><p>为路由指定了名称后,我们可以使用全局辅助函数 <code class=" language-php">route</code> 来生成 <code class=" language-php"><span class="token constant">URL</span></code> 或者重定向到该条路由:</p><pre class=" language-php"><code class=" language-php"><span class="token comment" spellcheck="true">// 生成 URL...
</span><span class="token variable">$url</span> <span class="token operator">=</span> <span class="token function">route<span class="token punctuation">(</span></span><span class="token string">'profile'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment" spellcheck="true">
// 生成重定向...
</span><span class="token keyword">return</span> <span class="token function">redirect<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">route<span class="token punctuation">(</span></span><span class="token string">'profile'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>如果是有定义参数的命名路由,可以把参数作为 <code class=" language-php">route</code> 函数的第二个参数传入,指定的参数将会自动插入到 <code class=" language-php"><span class="token constant">URL</span></code> 中对应的位置:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'user/{id}/profile'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">name<span class="token punctuation">(</span></span><span class="token string">'profile'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$url</span> <span class="token operator">=</span> <span class="token function">route<span class="token punctuation">(</span></span><span class="token string">'profile'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'id'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="route-groups"></a></p><h2><a href="#route-groups">路由组</a></h2><p>路由组允许共享路由属性,例如中间件和命名空间等,我们没有必要为每个路由单独设置共有属性,共有属性会以数组的形式放到 <code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span>group</code> 方法的第一个参数中。</p><p><a name="route-group-middleware"></a></p><h3>中间件</h3><p>要给路由组中定义的所有路由分配中间件,可以在路由组中使用 <code class=" language-php">middleware</code> 键,中间件将会依照列表内指定的顺序运行:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">group<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token string">'middleware'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">'auth'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'/'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // 使用 `Auth` 中间件
</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'user/profile'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // 使用 `Auth` 中间件
</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="route-group-namespaces"></a></p><h3>命名空间</h3><p>另一个常见的例子是,为控制器组指定公共的 <code class=" language-php"><span class="token constant">PHP</span></code> 命名空间。这时使用 <code class=" language-php"><span class="token keyword">namespace</span></code> 参数来指定组内所有控制器的公共命名空间:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">group<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token string">'namespace'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">'Admin'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // 在 "App\Http\Controllers\Admin" 命名空间下的控制器
</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>请记住,默认 <code class=" language-php">RouteServiceProvider</code> 会在命名空间组中引入你的路由文件,让你不用指定完整的 <code class=" language-php">App\<span class="token package">Http<span class="token punctuation">\</span>Controllers</span></code> 命名空间前缀就能注册控制器路由,因此,我们在定义的时候只需要指定命名空间 <code class=" language-php">App\<span class="token package">Http<span class="token punctuation">\</span>Controllers</span></code> 以后的部分。</p><p><a name="route-group-sub-domain-routing"></a></p><h3>子域名路由</h3><p>路由组也可以用作子域名的通配符,子域名可以像 URI 一样当作路由组的参数,因此允许把捕获的子域名一部分用于我们的路由或控制器。可以使用路由组属性的 <code class=" language-php">domain</code> 键声明子域名。</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">group<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token string">'domain'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">'{account}.myapp.com'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'user/{id}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$account</span><span class="token punctuation">,</span> <span class="token variable">$id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="route-group-prefixes"></a></p><h3>路由前缀</h3><p>通过路由组数组属性中的 <code class=" language-php">prefix</code> 键可以给每个路由组中的路由加上指定的 URI 前缀,例如,我们可以给路由组中所有的 URI 加上路由前缀 <code class=" language-php">admin</code> :</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">group<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token string">'prefix'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">'admin'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'users'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // 匹配包含 "/admin/users" 的 URL
</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="route-model-binding"></a></p><h2><a href="#route-model-binding">路由模型绑定</a></h2><p>当向路由控制器中注入模型 ID 时,我们通常需要查询这个 ID 对应的模型,Laravel 路由模型绑定提供了一个方便的方法自动将模型注入到我们的路由中,例如,除了注入一个用户的 ID,你也可以注入与指定 ID 匹配的完整 <code class=" language-php">User</code> 类实例。</p><p><a name="implicit-binding"></a></p><h3>隐式绑定</h3><p>Laravel 会自动解析定义在路由或控制器方法(方法包含和路由片段匹配的已声明类型变量)中的 Eloquent 模型,例如:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'api/users/{user}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span>App\<span class="token package">User</span> <span class="token variable">$user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">email</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>在这个例子中,由于类型声明了 Eloquent 模型 <code class=" language-php">App\<span class="token package">User</span></code>,对应的变量名 <code class=" language-php"><span class="token variable">$user</span></code> 会匹配路由片段中的 <code class=" language-php"><span class="token punctuation">{</span>user<span class="token punctuation">}</span></code>,这样,Laravel 会自动注入与请求 URI 中传入的 ID 对应的用户模型实例。</p><p>如果数据库中找不到对应的模型实例,将会自动生成产生一个 404 HTTP 响应。</p><h4>自定义键名</h4><p>如果你想要隐式模型绑定除 <code class=" language-php">id</code> 以外的数据库字段,你可以重写 Eloquent 模型类的 <code class=" language-php">getRouteKeyName</code> 方法:</p><pre class=" language-php"><code class=" language-php"><span class="token comment" spellcheck="true">/**
* 为路由模型获取键名
*
* @return string
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">getRouteKeyName<span class="token punctuation">(</span></span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token string">'slug'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre><p><a name="explicit-binding"></a></p><h3>显式绑定</h3><p>使用路由的 <code class=" language-php">model</code> 方法来为已有参数声明 class 。你应该在 <code class=" language-php">RouteServiceProvider</code> 类中的 <code class=" language-php">boot</code> 方法内定义这些显式绑定:</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">boot<span class="token punctuation">(</span></span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token scope"><span class="token keyword">parent</span><span class="token punctuation">::</span></span><span class="token function">boot<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">model<span class="token punctuation">(</span></span><span class="token string">'user'</span><span class="token punctuation">,</span> <span class="token scope">App<span class="token punctuation">\</span>User<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre><p>接着,定义包含 <code class=" language-php"><span class="token punctuation">{</span>user<span class="token punctuation">}</span></code> 参数的路由:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token string">'profile/{user}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span>App\<span class="token package">User</span> <span class="token variable">$user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>因为我们已经绑定 <code class=" language-php"><span class="token punctuation">{</span>user<span class="token punctuation">}</span></code> 参数至 <code class=" language-php">App\<span class="token package">User</span></code> 模型,所以 <code class=" language-php">User</code> 实例将被注入该路由。举个例子,一个至 <code class=" language-php">profile<span class="token operator">/</span><span class="token number">1</span></code> 的请求会注入 ID 为 1 的 <code class=" language-php">User</code> 实例。</p><blockquote><p><strong>注意:</strong>如果在数据库不存在对应 ID 的数据,就会自动抛出一个 404 异常。</p></blockquote><h4>自定义解析逻辑</h4><p>如果你想要使用自定义的解析逻辑,需要使用 <code class=" language-php"><span class="token scope">Route<span class="token punctuation">::</span></span>bind</code> 方法,传递到 <code class=" language-php">bind</code> 方法的闭包会获取到 URI 请求参数中的值,并且返回你想要在该路由中注入的类实例:</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">boot<span class="token punctuation">(</span></span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token scope"><span class="token keyword">parent</span><span class="token punctuation">::</span></span><span class="token function">boot<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">bind<span class="token punctuation">(</span></span><span class="token string">'user'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token scope">App<span class="token punctuation">\</span>User<span class="token punctuation">::</span></span><span class="token function">where<span class="token punctuation">(</span></span><span class="token string">'name'</span><span class="token punctuation">,</span> <span class="token variable">$value</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">first<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre><p><a name="form-method-spoofing"></a></p><h2><a href="#form-method-spoofing">表单方法伪造</a></h2><p>HTML 表单没有支持 <code class=" language-php"><span class="token constant">PUT</span></code>、<code class=" language-php"><span class="token constant">PATCH</span></code> 或 <code class=" language-php"><span class="token constant">DELETE</span></code> 动作。所以在定义要在 HTML 表单中调用的 <code class=" language-php"><span class="token constant">PUT</span></code>、<code class=" language-php"><span class="token constant">PATCH</span></code> 或 <code class=" language-php"><span class="token constant">DELETE</span></code> 路由时,你将需要在表单中增加隐藏的 <code class=" language-php">_method</code> 字段。 <code class=" language-php">_method</code> 字段的值将被作为 HTTP 的请求方法使用:</p><pre class=" language-php"><code class=" language-php"><span class="token markup"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>form</span> <span class="token attr-name">action</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>/foo/bar<span class="token punctuation">"</span></span> <span class="token attr-name">method</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>POST<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></span>
<span class="token markup"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>hidden<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>_method<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>PUT<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></span>
<span class="token markup"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>hidden<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>_token<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{{ csrf_token() }}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></span>
<span class="token markup"><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>form</span><span class="token punctuation">></span></span></span></code></pre><p>你也可以使用辅助函数 <code class=" language-php">method_field</code> 来生成隐藏的输入字段 <code class=" language-php">_method</code>:</p><pre class=" language-php"><code class=" language-php"><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token function">method_field<span class="token punctuation">(</span></span><span class="token string">'PUT'</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><p><a name="accessing-the-current-route"></a></p><h2><a href="#accessing-the-current-route">获取当前路由信息</a></h2><p>你可以使用 <code class=" language-php">Route</code> 上的 <code class=" language-php">current</code>, <code class=" language-php">currentRouteName</code>, and <code class=" language-php">currentRouteAction</code> 方法来访问处理当前输入请求的路由信息:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$route</span> <span class="token operator">=</span> <span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">current<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$name</span> <span class="token operator">=</span> <span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">currentRouteName<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$action</span> <span class="token operator">=</span> <span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">currentRouteAction<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>完整的方法列表请参考 <a href="http://laravel.com/api/5.4/Illuminate/Routing/Router.html">Route facade</a> 和 <a href="http://laravel.com/api/5.4/Illuminate/Routing/Route.html">Route 实例</a></p><h2>译者署名</h2><table><thead><tr><th>用户名</th><th>头像</th><th>职能</th><th>签名</th></tr></thead><tbody><tr><td><a href="https://github.com/zhouzihanntu">@zhouzihanntu</a></td><td><img class="avatar-66 rm-style" src="https://avatars0.githubusercontent.com/u/14007659?v=3&s=460"></td><td>翻译</td><td></td></tr></tbody></table></article>
- 入门指南
- 安装
- 配置信息
- 文件夹结构
- 请求周期
- 开发环境部署
- Valet
- Homestead
- 核心概念
- 服务提供者
- Facades
- Contracts
- 服务容器
- HTTP 层
- 路由
- 中间件
- CSRF 保护
- 控制器
- 请求
- 响应
- 视图
- Session
- 表单验证
- 前端
- Blade 模板
- 本地化
- 前端指南
- 编辑资源 Mix
- 安全
- API 认证
- 用户认证
- 用户授权
- 加密解密
- 哈希
- 重置密码
- 数据库
- 快速入门
- 查询构造器
- 分页
- 数据库迁移
- Redis
- 数据填充
- Eloquent ORM
- Eloquent ORM快速入门
- 模型关联
- Eloquent 集合
- 修改器
- 序列化
- 综合话题
- Artisan 命令行
- 广播系统
- 缓存系统
- 集合
- 错误与日志
- 事件系统
- 文件存储
- 辅助函数
- 邮件发送
- 消息通知
- 扩展包开发
- 队列
- 任务调度