<article><h1>Eloquent: 關聯</h1><ul><li><a href="#introduction">簡介</a></li><li><a href="#defining-relationships">定義關聯</a><ul><li><a href="#one-to-one">一對一</a></li><li><a href="#one-to-many">一對多</a></li><li><a href="#one-to-many-inverse">一對多(反向關聯)</a></li><li><a href="#many-to-many">多對多</a></li><li><a href="#has-many-through">遠層一對多</a></li><li><a href="#polymorphic-relations">多態關聯</a></li><li><a href="#many-to-many-polymorphic-relations">多態多對多關聯</a></li></ul></li><li><a href="#querying-relations">查找關聯</a><ul><li><a href="#relationship-methods-vs-dynamic-properties">關聯方法和動態屬性</a></li><li><a href="#querying-relationship-existence">查找關聯是否存在</a></li><li><a href="#counting-related-models">關聯數據計數</a></li></ul></li><li><a href="#eager-loading">預加載</a><ul><li><a href="#constraining-eager-loads">預加載條件限制</a></li><li><a href="#lazy-eager-loading">延遲預加載</a></li></ul></li><li><a href="#inserting-and-updating-related-models">插入 & 更新關聯模型</a><ul><li><a href="#the-save-method"><code class=" language-php">save</code> 方法</a></li><li><a href="#the-create-method"><code class=" language-php">create</code> 方法</a></li><li><a href="#updating-belongs-to-relationships">更新「從屬」關聯</a></li><li><a href="#updating-many-to-many-relationships">多對多關聯</a></li></ul></li><li><a href="#touching-parent-timestamps">連動父級時間戳</a></li></ul><p><a name="introduction"></a></p><h2><a href="#introduction">簡介</a></h2><p>數據表之間經常會互相進行關聯。例如,一篇博客文章可能會有多條評論,或是一張訂單可能對應一個下單客戶。Eloquent 讓管理和處理這些關聯變得很容易,同時也支持多種類型的關聯:</p><ul><li><a href="#one-to-one">一對一</a></li><li><a href="#one-to-many">一對多</a></li><li><a href="#many-to-many">多對多</a></li><li><a href="#has-many-through">遠層一對多</a></li><li><a href="#polymorphic-relations">多態關聯</a></li><li><a href="#many-to-many-polymorphic-relations">多態多對多關聯</a></li></ul><p><a name="defining-relationships"></a></p><h2><a href="#defining-relationships">定義關聯</a></h2><p>你可在 Eloquent 模型類內中,把 Eloquent 關聯定義成方法(methods)。因為,關聯就像 Eloquent 模型一樣,也可以作為強大的 <a href="/docs/5.4/queries">查詢語句構造器</a>,定義關聯為方法,為其提供了強而有力的鏈式調用及查找功能。例如,我們可以在 <code class=" language-php">posts</code> 關聯的鏈式調用中附加一個約束條件:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">posts<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">where<span class="token punctuation">(</span></span><span class="token string">'active'</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>不過,在深入了解使用關聯之前,先讓我們來學習如何定義每個類型:</p><p><a name="one-to-one"></a></p><h3>一對一</h3><p>「一對一」關聯是一個非常基本的關聯關系。舉個例子,一個 <code class=" language-php">User</code> 模型會關聯一個 <code class=" language-php">Phone</code> 模型。為了定義這種關聯關系,我們需要在 <code class=" language-php">User</code> 模型中寫一個 <code class=" language-php">phone</code> 方法。且 <code class=" language-php">phone</code> 方法應該調用 <code class=" language-php">hasOne</code> 方法并返回其結果:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 獲取與用戶關聯的電話號碼
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">phone<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">hasOne<span class="token punctuation">(</span></span><span class="token string">'App\Phone'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre><p>第一個傳到 <code class=" language-php">hasOne</code> 方法里的參數是關聯模型的類名。一旦定義好兩者之間關聯,我們就可以通過使用 Eloquent 的動態屬性來獲取關聯記錄。動態屬性允許你訪問關聯方法,如同他們是定義在模型中的屬性:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$phone</span> <span class="token operator">=</span> <span class="token scope">User<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">phone</span><span class="token punctuation">;</span></code></pre><p>Eloquent 會假設對應關聯的外鍵名稱是基于模型名稱的。在這個例子里,它會自動假設 <code class=" language-php">Phone</code> 模型擁有 <code class=" language-php">user_id</code> 外鍵。如果你想要重寫這個約定,則可以傳入第二個參數到 <code class=" language-php">hasOne</code> 方法里。</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">return</span> <span class="token this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">hasOne<span class="token punctuation">(</span></span><span class="token string">'App\Phone'</span><span class="token punctuation">,</span> <span class="token string">'foreign_key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>此外,Eloquent 假設外鍵會和上層模型的 <code class=" language-php">id</code> 字段(或者自定義的 <code class=" language-php"><span class="token variable">$primaryKey</span></code>)的值相匹配。換句話說,Eloquent 會尋找用戶的 <code class=" language-php">id</code> 字段與 <code class=" language-php">Phone</code> 模型的 <code class=" language-php">user_id</code> 字段的值相同的紀錄。如果你想讓關聯使用 <code class=" language-php">id</code> 以外的值,則可以傳遞第三個參數至 <code class=" language-php">hasOne</code> 方法來指定你自定義的鍵:</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">return</span> <span class="token this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">hasOne<span class="token punctuation">(</span></span><span class="token string">'App\Phone'</span><span class="token punctuation">,</span> <span class="token string">'foreign_key'</span><span class="token punctuation">,</span> <span class="token string">'local_key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h4>定義反向關聯</h4><p>所以,我們可以從 <code class=" language-php">User</code> 模型訪問到 <code class=" language-php">Phone</code> 模型。現在,讓我們在 <code class=" language-php">Phone</code> 模型上定義一個關聯,此關聯能夠讓我們訪問擁有此電話的 <code class=" language-php">User</code> 模型。我們可以定義與 <code class=" language-php">hasOne</code> 關聯相對應的 <code class=" language-php">belongsTo</code> 方法:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">Phone</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 獲取擁有該電話的用戶模型。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">user<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsTo<span class="token punctuation">(</span></span><span class="token string">'App\User'</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">Phone</code> 模型的 <code class=" language-php">user_id</code> 至 <code class=" language-php">User</code> 模型的 <code class=" language-php">id</code>。Eloquent 判斷的默認外鍵名稱參考自關聯模型的方法名稱,并會在方法名稱后面加上 <code class=" language-php">_id</code>。當然,如果 <code class=" language-php">Phone</code> 模型的外鍵不是 <code class=" language-php">user_id</code>,則可以傳遞自定義鍵名作為 <code class=" language-php">belongsTo</code> 方法的第二個參數:</p><pre class=" language-php"><code class=" language-php"><span class="token comment" spellcheck="true">/**
* 獲取擁有該電話的用戶模型。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">user<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsTo<span class="token punctuation">(</span></span><span class="token string">'App\User'</span><span class="token punctuation">,</span> <span class="token string">'foreign_key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre><p>如果你的父級模型不是使用 <code class=" language-php">id</code> 作為主鍵,或是希望以不同的字段來連接下層模型,則可以傳遞第三個參數至 <code class=" language-php">belongsTo</code> 方法來指定父級數據表的自定義鍵:</p><pre class=" language-php"><code class=" language-php"><span class="token comment" spellcheck="true">/**
* 獲取擁有該電話的用戶模型。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">user<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsTo<span class="token punctuation">(</span></span><span class="token string">'App\User'</span><span class="token punctuation">,</span> <span class="token string">'foreign_key'</span><span class="token punctuation">,</span> <span class="token string">'other_key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre><p><a name="one-to-many"></a></p><h3>一對多</h3><p>一個「一對多」關聯用于定義單個模型擁有任意數量的其它關聯模型。例如,一篇博客文章可能會有無限多個評論。就像其它的 Eloquent 關聯一樣,可以通過在 Eloquent 模型中寫一個函數來定義一對多關聯:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">Post</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 獲取這篇博文下的所有評論。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">comments<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">hasMany<span class="token punctuation">(</span></span><span class="token string">'App\Comment'</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">Comment</code> 模型上正確的外鍵字段。按約定來說,Eloquent 會取用自身模型的名稱的「Snake Case」,并在后方加上 <code class=" language-php">_id</code>。所以,以此例來說,Eloquent 會假設 <code class=" language-php">Comment</code> 模型的外鍵是 <code class=" language-php">post_id</code>。</p><p>一旦關聯被定義,則可以通過 <code class=" language-php">comments</code> 屬性來訪問評論的集合。切記,因為 Eloquent 提供了「動態屬性」,因此我們可以對關聯方法進行訪問,就像他們是在模型中定義的屬性一樣:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$comments</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Post<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">comments</span><span class="token punctuation">;</span>
<span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$comments</span> <span class="token keyword">as</span> <span class="token variable">$comment</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span></code></pre><p>當然,因為所有的關聯也都提供了查詢語句構造器的功能,因此你可以對獲取到的評論進一步增加條件,通過調用 <code class=" language-php">comments</code> 方法然后在該方法后面鏈式調用查詢條件:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$comments</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Post<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">comments<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">where<span class="token punctuation">(</span></span><span class="token string">'title'</span><span class="token punctuation">,</span> <span class="token string">'foo'</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></code></pre><p>就像 <code class=" language-php">hasOne</code> 方法,你也可以通過傳遞額外的參數至 <code class=" language-php">hasMany</code> 方法來重寫外鍵與本地鍵:</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">return</span> <span class="token this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">hasMany<span class="token punctuation">(</span></span><span class="token string">'App\Comment'</span><span class="token punctuation">,</span> <span class="token string">'foreign_key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">hasMany<span class="token punctuation">(</span></span><span class="token string">'App\Comment'</span><span class="token punctuation">,</span> <span class="token string">'foreign_key'</span><span class="token punctuation">,</span> <span class="token string">'local_key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="one-to-many-inverse"></a></p><h3>一對多(反向關聯)</h3><p>現在我們已經能訪問到所有文章的評論,讓我們來接著定義一個通過評論訪問所屬文章的關聯。若要定義相對于 <code class=" language-php">hasMany</code> 的關聯,可在子級模型定義一個叫做 <code class=" language-php">belongsTo</code> 方法的關聯函數:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">Comment</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 獲取該評論所屬的文章模型。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">post<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsTo<span class="token punctuation">(</span></span><span class="token string">'App\Post'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre><p>一旦關聯被定義之后,則可以通過 <code class=" language-php">post</code> 的「動態屬性」來獲取 <code class=" language-php">Comment</code> 模型相對應的 <code class=" language-php">Post</code> 模型:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$comment</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Comment<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">echo</span> <span class="token variable">$comment</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">post</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">title</span><span class="token punctuation">;</span></code></pre><p>在上述例子中,Eloquent 會嘗試將 <code class=" language-php">Comment</code> 模型的 <code class=" language-php">post_id</code> 與 <code class=" language-php">Post</code> 模型的 <code class=" language-php">id</code> 進行匹配。Eloquent 判斷的默認外鍵名稱參考自關聯模型的方法,并在方法名稱后面加上 <code class=" language-php">_id</code>。當然,如果 <code class=" language-php">Comment</code> 模型的外鍵不是 <code class=" language-php">post_id</code>,則可以傳遞自定義鍵名作為 <code class=" language-php">belongsTo</code> 方法的第二個參數:</p><pre class=" language-php"><code class=" language-php"><span class="token comment" spellcheck="true">/**
* 獲取該評論所屬的文章模型。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">post<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsTo<span class="token punctuation">(</span></span><span class="token string">'App\Post'</span><span class="token punctuation">,</span> <span class="token string">'foreign_key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre><p>如果你的父級模型不是使用 <code class=" language-php">id</code> 作為主鍵,或是你希望以不同的字段來連接下層模型,則可以傳遞第三個參數給 <code class=" language-php">belongsTo</code> 方法來指定上層數據表的自定義鍵:</p><pre class=" language-php"><code class=" language-php"><span class="token comment" spellcheck="true">/**
* 獲取該評論所屬的文章模型。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">post<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsTo<span class="token punctuation">(</span></span><span class="token string">'App\Post'</span><span class="token punctuation">,</span> <span class="token string">'foreign_key'</span><span class="token punctuation">,</span> <span class="token string">'other_key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre><p><a name="many-to-many"></a></p><h3>多對多</h3><p>「多對多」關聯要稍微比 <code class=" language-php">hasOne</code> 及 <code class=" language-php">hasMany</code> 關聯復雜。如,一個用戶可能擁有多種身份,而一種身份能同時被多個用戶擁有。舉例來說,很多用戶都擁有「管理員」的身份。要定義這種關聯,需要使用三個數據表:<code class=" language-php">users</code>、<code class=" language-php">roles</code> 和 <code class=" language-php">role_user</code>。<code class=" language-php">role_user</code> 表命名是以相關聯的兩個模型數據表來依照字母順序命名,并包含了 <code class=" language-php">user_id</code> 和 <code class=" language-php">role_id</code> 字段。</p><p>多對多關聯通過編寫一個在自身 Eloquent 類調用的 <code class=" language-php">belongsToMany</code> 的方法來定義。舉個例子,讓我們在 <code class=" language-php">User</code> 模型中定義 <code class=" language-php">roles</code> 方法:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 屬于該用戶的身份。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">roles<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsToMany<span class="token punctuation">(</span></span><span class="token string">'App\Role'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre><p>一旦關聯被定義,則可以使用 <code class=" language-php">roles</code> 動態屬性來訪問用戶的身份:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$user</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>User<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">roles</span> <span class="token keyword">as</span> <span class="token variable">$role</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span></code></pre><p>當然,就如所有其它的關聯類型一樣,你也可以調用 <code class=" language-php">roles</code> 方法并在該關聯之后鏈式調用查詢條件:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$roles</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>User<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">roles<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">orderBy<span class="token punctuation">(</span></span><span class="token string">'name'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>如前文提到那樣,Eloquent 會合并兩個關聯模型的名稱并依照字母順序命名。當然你也可以隨意重寫這個約定。可通過傳遞第二個參數至 <code class=" language-php">belongsToMany</code> 方法來實現:</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">return</span> <span class="token this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsToMany<span class="token punctuation">(</span></span><span class="token string">'App\Role'</span><span class="token punctuation">,</span> <span class="token string">'role_user'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>除了自定義合并數據表的名稱,你也可以通過傳遞額外參數至 <code class=" language-php">belongsToMany</code> 方法來自定義數據表里的鍵的字段名稱。第三個參數是你定義在關聯中的模型外鍵名稱,而第四個參數則是你要合并的模型外鍵名稱:</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">return</span> <span class="token this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsToMany<span class="token punctuation">(</span></span><span class="token string">'App\Role'</span><span class="token punctuation">,</span> <span class="token string">'role_user'</span><span class="token punctuation">,</span> <span class="token string">'user_id'</span><span class="token punctuation">,</span> <span class="token string">'role_id'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h4>定義相對的關聯</h4><p>要定義相對于多對多的關聯,只需簡單的放置另一個名為 <code class=" language-php">belongsToMany</code> 的方法到你關聯的模型上。讓我們接著以用戶身份為例,在 <code class=" language-php">Role</code> 模型中定義 <code class=" language-php">users</code> 方法:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">Role</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 屬于該身份的用戶。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">users<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsToMany<span class="token punctuation">(</span></span><span class="token string">'App\User'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre><p>如你所見,此定義除了簡單的參考 <code class=" language-php">App\<span class="token package">User</span></code> 模型外,與 <code class=" language-php">User</code> 的對應完全相同。因為我們重復使用了 <code class=" language-php">belongsToMany</code> 方法,當定義相對于多對多的關聯時,所有常用的自定義數據表與鍵的選項都是可用的。</p><h4>獲取中間表字段</h4><p>正如你所知,要操作多對多關聯需要一個中間數據表。Eloquent 提供了一些有用的方法來和這張表進行交互。例如,假設 <code class=" language-php">User</code> 對象關聯到很多的 <code class=" language-php">Role</code> 對象。訪問這些關聯對象時,我們可以在模型中使用 <code class=" language-php">pivot</code> 屬性來訪問中間數據表的數據:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$user</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>User<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">roles</span> <span class="token keyword">as</span> <span class="token variable">$role</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">echo</span> <span class="token variable">$role</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">pivot</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">created_at</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre><p>注意我們取出的每個 <code class=" language-php">Role</code> 模型對象,都會被自動賦予 <code class=" language-php">pivot</code> 屬性。此屬性代表中間表的模型,它可以像其它的 Eloquent 模型一樣被使用。</p><p>默認情況下,<code class=" language-php">pivot</code> 對象只提供模型的鍵。如果你的 pivot 數據表包含了其它的屬性,則可以在定義關聯方法時指定那些字段:</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">return</span> <span class="token this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsToMany<span class="token punctuation">(</span></span><span class="token string">'App\Role'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">withPivot<span class="token punctuation">(</span></span><span class="token string">'column1'</span><span class="token punctuation">,</span> <span class="token string">'column2'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>如果你想要中間表自動維護 <code class=" language-php">created_at</code> 和 <code class=" language-php">updated_at</code> 時間戳,可在定義關聯方法時加上 <code class=" language-php">withTimestamps</code> 方法:</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">return</span> <span class="token this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsToMany<span class="token punctuation">(</span></span><span class="token string">'App\Role'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">withTimestamps<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h4>使用中間表來過濾關聯數據</h4><p>你可以使用 <code class=" language-php">wherePivot</code> 和 <code class=" language-php">wherePivotIn</code> 來增加中間件表過濾條件:</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">return</span> <span class="token this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsToMany<span class="token punctuation">(</span></span><span class="token string">'App\Role'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">wherePivot<span class="token punctuation">(</span></span><span class="token string">'approved'</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsToMany<span class="token punctuation">(</span></span><span class="token string">'App\Role'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">wherePivotIn<span class="token punctuation">(</span></span><span class="token string">'priority'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h4>定義自定義中間表模型</h4><p>如果你想定義一個自定義模型來表示你中間表的關聯,則可以在定義關聯時調用 <code class=" language-php">using</code> 方法。所有用來表示中間表關聯的自定義模型必須擴展自 <code class=" language-php">Illuminate\<span class="token package">Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Relations<span class="token punctuation">\</span>Pivot</span></code> 類:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">Role</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 屬于該身份的用戶。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">users<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsToMany<span class="token punctuation">(</span></span><span class="token string">'App\User'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">using<span class="token punctuation">(</span></span><span class="token string">'App\UserRole'</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="has-many-through"></a></p><h3>遠層一對多</h3><p>「遠層一對多」提供了方便簡短的方法來通過中間的關聯獲取遠層的關聯。例如,一個 <code class=" language-php">Country</code> 模型可能通過中間的 <code class=" language-php">Users</code> 模型關聯到多個 <code class=" language-php">Posts</code> 模型。讓我們來看看定義此種關聯的數據表:</p><pre class=" language-php"><code class=" language-php">countries
id <span class="token operator">-</span> integer
name <span class="token operator">-</span> string
users
id <span class="token operator">-</span> integer
country_id <span class="token operator">-</span> integer
name <span class="token operator">-</span> string
posts
id <span class="token operator">-</span> integer
user_id <span class="token operator">-</span> integer
title <span class="token operator">-</span> string</code></pre><p>雖然 <code class=" language-php">posts</code> 本身不包含 <code class=" language-php">country_id</code> 字段,但 <code class=" language-php">hasManyThrough</code> 關聯通過 <code class=" language-php"><span class="token variable">$country</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">posts</span></code> 來讓我們可以訪問一個國家的文章。若運行此查找,則 Eloquent 會檢查中間表 <code class=" language-php">users</code> 的 <code class=" language-php">country_id</code>。在找到匹配的用戶 ID 后,就會在 <code class=" language-php">posts</code> 數據表中使用它們來進行查找。</p><p>現在我們已經檢查完了關聯的數據表結構,讓我們來接著在 <code class=" language-php">Country</code> 模型中定義它:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">Country</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 獲取該國家的所有文章。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">posts<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">hasManyThrough<span class="token punctuation">(</span></span><span class="token string">'App\Post'</span><span class="token punctuation">,</span> <span class="token string">'App\User'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre><p><code class=" language-php">hasManyThrough</code> 方法的第一個參數為我們希望最終訪問的模型名稱,而第二個參數為中間模型的名稱。</p><p>當運行關聯查找時,通常會使用 Eloquent 的外鍵約定。如果你想要自定義關聯的鍵,則可以將它們傳遞至 <code class=" language-php">hasManyThrough</code> 方法的第三與第四個參數。第三個參數為中間模型的外鍵名稱,而第四個參數為最終模型的外鍵名稱,第五個參數則為本地鍵。</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">class</span> <span class="token class-name">Country</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">posts<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">hasManyThrough<span class="token punctuation">(</span></span>
<span class="token string">'App\Post'</span><span class="token punctuation">,</span> <span class="token string">'App\User'</span><span class="token punctuation">,</span>
<span class="token string">'country_id'</span><span class="token punctuation">,</span> <span class="token string">'user_id'</span><span class="token punctuation">,</span> <span class="token string">'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><a name="polymorphic-relations"></a></p><h3>多態關聯</h3><h4>數據表結構</h4><p>多態關聯允許一個模型在單個關聯中從屬一個以上其它模型。舉個例子,想象一下使用你應用的用戶可以「評論」文章和視頻。使用多態關聯關系,您可以使用一個 <code class=" language-php">comments</code> 數據表就可以同時滿足兩個使用場景。首先,讓我們觀察一下用來創建這關聯的數據表結構:</p><pre class=" language-php"><code class=" language-php">posts
id <span class="token operator">-</span> integer
title <span class="token operator">-</span> string
body <span class="token operator">-</span> text
videos
id <span class="token operator">-</span> integer
title <span class="token operator">-</span> string
url <span class="token operator">-</span> string
comments
id <span class="token operator">-</span> integer
body <span class="token operator">-</span> text
commentable_id <span class="token operator">-</span> integer
commentable_type <span class="token operator">-</span> string</code></pre><p>有兩個需要注意的字段是 <code class=" language-php">comments</code> 表中的 <code class=" language-php">commentable_id</code> 和 <code class=" language-php">commentable_type</code>。其中, <code class=" language-php">commentable_id</code> 用于存放文章或者視頻的 id ,而 <code class=" language-php">commentable_type</code> 用于存放所屬模型的類名。注意的是, <code class=" language-php">commentable_type</code> 是當我們訪問 <code class=" language-php">commentable</code> 關聯時, ORM 用于判斷所屬的模型是哪個「類型」。</p><h4>模型結構</h4><p>接著,讓我們來查看創建這種關聯所需的模型定義:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">Comment</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 獲取所有擁有的 commentable 模型。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">commentable<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">morphTo<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 keyword">class</span> <span class="token class-name">Post</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 獲取所有文章的評論。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">comments<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">morphMany<span class="token punctuation">(</span></span><span class="token string">'App\Comment'</span><span class="token punctuation">,</span> <span class="token string">'commentable'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">class</span> <span class="token class-name">Video</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 獲取所有視頻的評論。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">comments<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">morphMany<span class="token punctuation">(</span></span><span class="token string">'App\Comment'</span><span class="token punctuation">,</span> <span class="token string">'commentable'</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>一旦你的數據表及模型被定義,則可以通過模型來訪問關聯。例如,若要訪問謀篇文章的所有評論,則可以簡單的使用 <code class=" language-php">comments</code> 動態屬性:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$post</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Post<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$post</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">comments</span> <span class="token keyword">as</span> <span class="token variable">$comment</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span></code></pre><p>你也可以從多態模型的多態關聯中,通過訪問調用 <code class=" language-php">morphTo</code> 的方法名稱來獲取擁有者,也就是此例子中 <code class=" language-php">Comment</code> 模型的 <code class=" language-php">commentable</code> 方法。所以,我們可以使用動態屬性來訪問這個方法:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$comment</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Comment<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$commentable</span> <span class="token operator">=</span> <span class="token variable">$comment</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">commentable</span><span class="token punctuation">;</span></code></pre><p><code class=" language-php">Comment</code> 模型的 <code class=" language-php">commentable</code> 關聯會返回 <code class=" language-php">Post</code> 或 <code class=" language-php">Video</code> 實例,這取決于評論所屬模型的類型。</p><h4>自定義多態關聯的類型字段</h4><p>默認情況下,Laravel 會使用「包含命名空間的類名」作為多態表的類型區分,例如,<code class=" language-php">Comment</code> 屬于 <code class=" language-php">Post</code> 或者 <code class=" language-php">Video</code> , <code class=" language-php">commentable_type</code> 的默認值可以分別是 <code class=" language-php">App\<span class="token package">Post</span></code> 或者 <code class=" language-php">App\<span class="token package">Video</span></code> 。然而,你也許會想使用應用中的內部結構來對數據庫進行解耦。在這個例子中,你可以定義一個「多態對照表」來指引 Eloquent 對各個模型使用自定義名稱而非類名:</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Relations<span class="token punctuation">\</span>Relation</span><span class="token punctuation">;</span>
<span class="token scope">Relation<span class="token punctuation">::</span></span><span class="token function">morphMap<span class="token punctuation">(</span></span><span class="token punctuation">[</span>
<span class="token string">'posts'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token scope">App<span class="token punctuation">\</span>Post<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span>
<span class="token string">'videos'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token scope">App<span class="token punctuation">\</span>Video<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><span class="token punctuation">;</span></code></pre><p>你需要在你自己的 <code class=" language-php">AppServiceProvider</code> 中的 <code class=" language-php">boot</code> 函數注冊這個 <code class=" language-php">morphMap</code> ,或者創建一個獨立且滿足你要求的服務提供者。</p><p><a name="many-to-many-polymorphic-relations"></a></p><h3>多態多對多關聯</h3><h4>數據表結構</h4><p>除了一般的多態關聯,你也可以定義「多對多」的多態關聯。例如,博客的 <code class=" language-php">Post</code> 和 <code class=" language-php">Video</code> 模型可以共用多態關聯至 <code class=" language-php">Tag</code> 模型。使用多對多的多態關聯能夠讓你的博客文章及圖片共用獨立標簽的單個列表。首先,讓我們先來查看數據表結構:</p><pre class=" language-php"><code class=" language-php">posts
id <span class="token operator">-</span> integer
name <span class="token operator">-</span> string
videos
id <span class="token operator">-</span> integer
name <span class="token operator">-</span> string
tags
id <span class="token operator">-</span> integer
name <span class="token operator">-</span> string
taggables
tag_id <span class="token operator">-</span> integer
taggable_id <span class="token operator">-</span> integer
taggable_type <span class="token operator">-</span> string</code></pre><h4>模型結構</h4><p>接著,我們已經準備好定義模型的關聯。<code class=" language-php">Post</code> 及 <code class=" language-php">Video</code> 模型都會擁有 <code class=" language-php">tags</code> 方法,并在該方法內調用自身 Eloquent 類的 <code class=" language-php">morphToMany</code> 方法:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">Post</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 獲取該文章的所有標簽。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">tags<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">morphToMany<span class="token punctuation">(</span></span><span class="token string">'App\Tag'</span><span class="token punctuation">,</span> <span class="token string">'taggable'</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>然后,在 <code class=" language-php">Tag</code> 模型上,你必須為每個要關聯的模型定義一個方法。因此,在這個例子中,我們需要定義一個 <code class=" language-php">posts</code> 方法及一個 <code class=" language-php">videos</code> 方法:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">Tag</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 獲取所有被賦予該標簽的文章。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">posts<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">morphedByMany<span class="token punctuation">(</span></span><span class="token string">'App\Post'</span><span class="token punctuation">,</span> <span class="token string">'taggable'</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 keyword">public</span> <span class="token keyword">function</span> <span class="token function">videos<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">morphedByMany<span class="token punctuation">(</span></span><span class="token string">'App\Video'</span><span class="token punctuation">,</span> <span class="token string">'taggable'</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>一旦你的數據表及模型被定義,則可以通過你的模型來訪問關聯。例如,你可以簡單的使用 <code class=" language-php">tags</code> 動態屬性來訪問文章的所有標簽:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$post</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Post<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$post</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">tags</span> <span class="token keyword">as</span> <span class="token variable">$tag</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span></code></pre><p>你也可以從多態模型的多態關聯中,通過訪問運行調用 <code class=" language-php">morphedByMany</code> 的方法名稱來獲取擁有者。在此例子中,就是 <code class=" language-php">Tag</code> 模型的 <code class=" language-php">posts</code> 或 <code class=" language-php">videos</code> 方法。因此,你可以通過訪問使用動態屬性來訪問這個方法:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$tag</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Tag<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$tag</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">videos</span> <span class="token keyword">as</span> <span class="token variable">$video</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span></code></pre><p><a name="querying-relations"></a></p><h2><a href="#querying-relations">查找關聯</a></h2><p>所有類型的 Eloquent 關聯都是通過方法來定義的,你可以通過調用這些方法來獲得關聯的一個實例,而不需要實際運行關聯的查找。此外,所有類型的 Eloquent 關聯也提供了 <a href="/docs/5.4/queries">查詢語句構造器</a> 的功能,讓你能夠在數據庫運行該 SQL 前,在關聯查找后面鏈式調用條件。</p><p>例如,假設有一個博客系統,其中 <code class=" language-php">User</code> 模型擁有許多關聯的 <code class=" language-php">Post</code> 模型:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 獲取該用戶的所有文章。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">posts<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">hasMany<span class="token punctuation">(</span></span><span class="token string">'App\Post'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre><p>你可以查找 <code class=" language-php">posts</code> 關聯并增加額外的條件至關聯,像這樣:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$user</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>User<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">posts<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">where<span class="token punctuation">(</span></span><span class="token string">'active'</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>你可以在關聯中使用 <a href="/docs/5.4/queries">查詢語句構造器</a> 中的任意方法,所以,歡迎查閱查詢語句構造器的相關文檔以便了解那些有助于你實現的方法。</p><p><a name="relationship-methods-vs-dynamic-properties"></a></p><h3>關聯方法與動態屬性</h3><p>如果你不需要增加額外的條件至 Eloquent 的關聯查找,則可以簡單的像訪問屬性一樣來訪問關聯。例如我們剛剛的 <code class=" language-php">User</code> 及 <code class=" language-php">Post</code> 模型示例,我們可以像這樣來訪問所有用戶的文章:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$user</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>User<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">posts</span> <span class="token keyword">as</span> <span class="token variable">$post</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> //
</span><span class="token punctuation">}</span></code></pre><p>動態屬性是「延遲加載」的,意味著它們只會在被訪問的時候才加載關聯數據。正因為如此,開發者通常需要使用 <a href="#eager-loading">預加載</a> 來預先加載關聯數據,關聯數據將會在模型加載后被訪問。預加載能有效減少你的 SQL 查詢語句。</p><p><a name="querying-relationship-existence"></a></p><h3>查找關聯是否存在</h3><p>當訪問模型的紀錄時,你可能希望根據關聯的存在來對結果進行限制。比方說你想獲取博客中那些至少擁有一條評論的文章。則可以通過傳遞名稱至關聯的 <code class=" language-php">has</code> 方法來實現:</p><pre class=" language-php"><code class=" language-php"><span class="token comment" spellcheck="true">// 獲取那些至少擁有一條評論的文章...
</span><span class="token variable">$posts</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Post<span class="token punctuation">::</span></span><span class="token function">has<span class="token punctuation">(</span></span><span class="token string">'comments'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">get<span class="token punctuation">(</span></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 comment" spellcheck="true">// 獲取所有至少有三條評論的文章...
</span><span class="token variable">$posts</span> <span class="token operator">=</span> <span class="token scope">Post<span class="token punctuation">::</span></span><span class="token function">has<span class="token punctuation">(</span></span><span class="token string">'comments'</span><span class="token punctuation">,</span> <span class="token string">'>='</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>也可以使用「點」符號來構造嵌套的 has 語句。例如,你可能想獲取那些至少有一條評論被投票的文章:</p><pre class=" language-php"><code class=" language-php"><span class="token comment" spellcheck="true">// 獲取所有至少有一條評論被評分的文章...
</span><span class="token variable">$posts</span> <span class="token operator">=</span> <span class="token scope">Post<span class="token punctuation">::</span></span><span class="token function">has<span class="token punctuation">(</span></span><span class="token string">'comments.votes'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>如果你想要更高級的用法,則可以使用 <code class=" language-php">whereHas</code> 和 <code class=" language-php">orWhereHas</code> 方法,在 has 查找里設置「where」條件。此方法可以讓你增加自定義條件至關聯條件中,例如對評論內容進行檢查:</p><pre class=" language-php"><code class=" language-php"><span class="token comment" spellcheck="true">// 獲取那些至少有一條評論包含 foo 的文章
</span><span class="token variable">$posts</span> <span class="token operator">=</span> <span class="token scope">Post<span class="token punctuation">::</span></span><span class="token function">whereHas<span class="token punctuation">(</span></span><span class="token string">'comments'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$query</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token variable">$query</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">'content'</span><span class="token punctuation">,</span> <span class="token string">'like'</span><span class="token punctuation">,</span> <span class="token string">'foo%'</span><span class="token punctuation">)</span><span class="token punctuation">;</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">get<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="counting-related-models"></a></p><h3>關聯數據計數</h3><p>如果你想對關聯數據進行計數但又不想再發起單獨的 SQL 請求,你可以使用 <code class=" language-php">withCount</code> 方法,此方法會在你的結果集中增加一個 <code class=" language-php"><span class="token punctuation">{</span>relation<span class="token punctuation">}</span>_count</code> 字段:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$posts</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Post<span class="token punctuation">::</span></span><span class="token function">withCount<span class="token punctuation">(</span></span><span class="token string">'comments'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$posts</span> <span class="token keyword">as</span> <span class="token variable">$post</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">echo</span> <span class="token variable">$post</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">comments_count</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 variable">$posts</span> <span class="token operator">=</span> <span class="token scope">Post<span class="token punctuation">::</span></span><span class="token function">withCount<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token string">'votes'</span><span class="token punctuation">,</span> <span class="token string">'comments'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$query</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token variable">$query</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">'content'</span><span class="token punctuation">,</span> <span class="token string">'like'</span><span class="token punctuation">,</span> <span class="token string">'foo%'</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 operator">-</span><span class="token operator">></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">echo</span> <span class="token variable">$posts</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">votes_count</span><span class="token punctuation">;</span>
<span class="token keyword">echo</span> <span class="token variable">$posts</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">comments_count</span><span class="token punctuation">;</span></code></pre><p><a name="eager-loading"></a></p><h2><a href="#eager-loading">預加載</a></h2><p>當通過屬性訪問 Eloquent 關聯時,該關聯數據會被「延遲加載」。意味著該關聯數據只有在你使用屬性訪問它時才會被加載。不過,Eloquent 可以在你查找上層模型時「預加載」關聯數據。預加載避免了 N + 1 查找的問題。要說明 N + 1 查找的問題,可試想一個關聯到 <code class=" language-php">Author</code> 的 <code class=" language-php">Book</code> 模型,如下所示:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">Book</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 獲取編寫該書的作者。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">author<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsTo<span class="token punctuation">(</span></span><span class="token string">'App\Author'</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 variable">$books</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Book<span class="token punctuation">::</span></span><span class="token function">all<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$books</span> <span class="token keyword">as</span> <span class="token variable">$book</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">echo</span> <span class="token variable">$book</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">author</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">name</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre><p>上方的循環會運行一次查找并取回所有數據表上的書籍,接著每本書會運行一次查找作者的操作。因此,若存在著 25 本書,則循環就會執行 26 次查找:1 次是查找所有書籍,其它 25 次則是在查找每本書的作者。</p><p>很幸運地,我們可以使用預加載來將查找的操作減少至 2 次。可在查找時使用 with 方法來指定想要預加載的關聯數據:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$books</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Book<span class="token punctuation">::</span></span><span class="token function">with<span class="token punctuation">(</span></span><span class="token string">'author'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$books</span> <span class="token keyword">as</span> <span class="token variable">$book</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">echo</span> <span class="token variable">$book</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">author</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">name</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre><p>對于該操作則只會執行兩條 SQL 語句:</p><pre class=" language-php"><code class=" language-php">select <span class="token operator">*</span> from books
select <span class="token operator">*</span> from authors where id in <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</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><h4>預加載多種關聯</h4><p>有時你可能想要在單次操作中預加載多種不同的關聯。要這么做,只需傳遞額外的參數至 <code class=" language-php">with</code> 方法即可:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$books</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Book<span class="token punctuation">::</span></span><span class="token function">with<span class="token punctuation">(</span></span><span class="token string">'author'</span><span class="token punctuation">,</span> <span class="token string">'publisher'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h4>嵌套預加載</h4><p>若要預加載嵌套關聯,則可以使用「點」語法。例如,讓我們在一個 Eloquent 語法中,預加載所有書籍的作者,及所有作者的個人聯系方式:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$books</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Book<span class="token punctuation">::</span></span><span class="token function">with<span class="token punctuation">(</span></span><span class="token string">'author.contacts'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="constraining-eager-loads"></a></p><h3>預加載條件限制</h3><p>有時你可能想要預加載關聯,并且指定預加載查詢的額外條件。如下所示:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$users</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>User<span class="token punctuation">::</span></span><span class="token function">with<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token string">'posts'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$query</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token variable">$query</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">'title'</span><span class="token punctuation">,</span> <span class="token string">'like'</span><span class="token punctuation">,</span> <span class="token string">'%first%'</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 operator">-</span><span class="token operator">></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>在這個例子里,Eloquent 只會預加載標題包含 <code class=" language-php">first</code> 的文章。當然,你也可以調用其它的 <a href="/docs/5.4/queries">查詢語句構造器</a> 來進一步自定義預加載的操作:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$users</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>User<span class="token punctuation">::</span></span><span class="token function">with<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token string">'posts'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$query</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token variable">$query</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">orderBy<span class="token punctuation">(</span></span><span class="token string">'created_at'</span><span class="token punctuation">,</span> <span class="token string">'desc'</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 operator">-</span><span class="token operator">></span><span class="token function">get<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="lazy-eager-loading"></a></p><h3>延遲預加載</h3><p>有時你可能需要在上層模型被獲取后才預加載關聯。當你需要來動態決定是否加載關聯模型時會很有幫助,如下所示:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$books</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Book<span class="token punctuation">::</span></span><span class="token function">all<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$someCondition</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token variable">$books</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">load<span class="token punctuation">(</span></span><span class="token string">'author'</span><span class="token punctuation">,</span> <span class="token string">'publisher'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre><p>如果你想設置預加載查詢的額外條件,則可以傳遞一個鍵值為你想要的關聯的數組至 <code class=" language-php">load</code> 方法。這個數組的值應是用于接收查詢實例的 <code class=" language-php">閉包</code> 實例:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$books</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">load<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token string">'author'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$query</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token variable">$query</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">orderBy<span class="token punctuation">(</span></span><span class="token string">'published_date'</span><span class="token punctuation">,</span> <span class="token string">'asc'</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="inserting-and-updating-related-models"></a></p><h2><a href="#inserting-and-updating-related-models">寫入關聯模型</a></h2><p><a name="the-save-method"></a></p><h3>Save 方法</h3><p>Eloquent 提供了便捷的方法來將新的模型增加至關聯中。例如,將新的 <code class=" language-php">Comment</code> 寫入至 <code class=" language-php">Post</code> 模型。除了手動設置 <code class=" language-php">Comment</code> 的 <code class=" language-php">post_id</code> 屬性外,你也可以直接使用關聯的 <code class=" language-php">save</code> 方法來寫入 <code class=" language-php">Comment</code>:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$comment</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">App<span class="token punctuation">\</span>Comment</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'message'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">'A new comment.'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$post</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Post<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$post</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">comments<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">save<span class="token punctuation">(</span></span><span class="token variable">$comment</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>注意我們并沒有使用動態屬性來訪問 <code class=" language-php">comments</code> 關聯。相反地,我們調用了 comments 方法來獲取關聯的實例。save 方法會自動在新的 <code class=" language-php">Comment</code> 模型中增加正確的 <code class=" language-php">post_id</code> 值。</p><p>如果你需要保存多個關聯模型,則可以使用 <code class=" language-php">saveMany</code> 方法:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$post</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Post<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$post</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">comments<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">saveMany<span class="token punctuation">(</span></span><span class="token punctuation">[</span>
<span class="token keyword">new</span> <span class="token class-name">App<span class="token punctuation">\</span>Comment</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'message'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">'A new comment.'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token keyword">new</span> <span class="token class-name">App<span class="token punctuation">\</span>Comment</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'message'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">'Another comment.'</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="the-create-method"></a></p><h3>Create 方法</h3><p>除了 <code class=" language-php">save</code> 與 <code class=" language-php">saveMany</code> 方法外,你也可以使用 <code class=" language-php">create</code> 方法,該方法允許傳入屬性的數組來建立模型并寫入數據庫。<code class=" language-php">save</code> 與 <code class=" language-php">create</code> 的不同之處在于,<code class=" language-php">save</code> 允許傳入一個完整的 Eloquent 模型實例,但 <code class=" language-php">create</code> 只允許傳入原始的 PHP 數組:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$post</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Post<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$comment</span> <span class="token operator">=</span> <span class="token variable">$post</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">comments<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">create<span class="token punctuation">(</span></span><span class="token punctuation">[</span>
<span class="token string">'message'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">'A new comment.'</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>在使用 create 方法前,請確認你已瀏覽了文檔的 <a href="/docs/5.4/eloquent#mass-assignment">批量賦值</a> 章節。</p><p><a name="updating-belongs-to-relationships"></a></p><h3>更新「從屬」關聯</h3><p>當更新一個 <code class=" language-php">belongsTo</code> 關聯時,可以使用 <code class=" language-php">associate</code> 方法。此方法會將外鍵設置到下層模型:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$account</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Account<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">account<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">associate<span class="token punctuation">(</span></span><span class="token variable">$account</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">save<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>當刪除一個 <code class=" language-php">belongsTo</code> 關聯時,你可以使用 <code class=" language-php">dissociate</code> 方法。此方法會置該關聯的外鍵為空 (null) :</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">account<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">dissociate<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">save<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="updating-many-to-many-relationships"></a></p><h3>多對多關聯</h3><h4>附加與卸除</h4><p>當使用多對多關聯時,Eloquent 提供了一些額外的輔助函數讓操作關聯模型更加方便。例如,讓我們假設一個用戶可以擁有多個身份,且每個身份都可以被多個用戶擁有。要附加一個規則至一個用戶,并連接模型以及將記錄寫入至中間表,則可以使用 <code class=" language-php">attach</code> 方法:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$user</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>User<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">roles<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">attach<span class="token punctuation">(</span></span><span class="token variable">$roleId</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 variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">roles<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">attach<span class="token punctuation">(</span></span><span class="token variable">$roleId</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'expires'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token variable">$expires</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>當然,我們有時也需要來移除用戶的身份。要移除一個多對多的紀錄,可使用 <code class=" language-php">detach</code> 方法。<code class=" language-php">detach</code> 方法會從中間表中移除正確的紀錄;當然,這兩個模型依然會存在于數據庫中:</p><pre class=" language-php"><code class=" language-php"><span class="token comment" spellcheck="true">// 移除用戶身上某一身份...
</span><span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">roles<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">detach<span class="token punctuation">(</span></span><span class="token variable">$roleId</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment" spellcheck="true">
// 移除用戶身上所有身份...
</span><span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">roles<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">detach<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>為了方便,attach 與 detach 都允許傳入 ID 數組:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$user</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>User<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">roles<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">detach<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">roles<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">attach<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token number">1</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span><span class="token string">'expires'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token variable">$expires</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h4>更新關聯</h4><p>你也可以使用 <code class=" language-php">sync</code> 方法去創建一個多對多的關聯。 <code class=" language-php">sync</code> 方法可以用數組形式的 IDs 插入中間的數據表。任何一個不存在于給定數組的 IDs 將會在中間表內被刪除。所以,操作完成之后,只有那些在給定數組內的 IDs 會被保留在中間表中。</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">roles<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">sync<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>你也可以通過 IDs 傳遞其他的附加中間表值:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">roles<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">sync<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token number">1</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span><span class="token string">'expires'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token boolean">true</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>如果你不想分離現有的 IDs ,你可以 <code class=" language-php">syncWithoutDetaching</code> 方法:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">roles<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">syncWithoutDetaching<span class="token punctuation">(</span></span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h4>在中間表上保存額外數據</h4><p>處理多對多關聯時, <code class=" language-php">save</code> 方法接收額外中間表屬性數組作為第二個參數:</p><pre class=" language-php"><code class=" language-php"><span class="token scope">App<span class="token punctuation">\</span>User<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">roles<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">save<span class="token punctuation">(</span></span><span class="token variable">$role</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'expires'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token variable">$expires</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h4>更新中間表記錄</h4><p>如果你需要更新中間表已存在的記錄,可以使用 <code class=" language-php">updateExistingPivot</code> 方法。這個方法接收中間記錄的外鍵和屬性數組進行更新:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$user</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>User<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$user</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">roles<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">updateExistingPivot<span class="token punctuation">(</span></span><span class="token variable">$roleId</span><span class="token punctuation">,</span> <span class="token variable">$attributes</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p><a name="touching-parent-timestamps"></a></p><h2><a href="#touching-parent-timestamps">連動父級時間戳</a></h2><p>當一個模型 <code class=" language-php">belongsTo</code> 或 <code class=" language-php">belongsToMany</code> 另一個模型時,像是一個 <code class=" language-php">Comment</code> 屬于一個 <code class=" language-php">Post</code>。這對于子級模型被更新時,要更新父級的時間戳相當有幫助。舉例來說,當一個 <code class=" language-php">Comment</code> 模型被更新時,你可能想要「連動」更新 <code class=" language-php">Post</code> 所屬的 <code class=" language-php">updated_at</code> 時間戳。Eloquent 使得此事相當容易。只要在關聯的下層模型中增加一個包含名稱的 <code class=" language-php">touches</code> 屬性即可:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter"><?php</span>
<span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">Comment</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span>
<span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">/**
* 所有的關聯將會被連動。
*
* @var array
*/</span>
<span class="token keyword">protected</span> <span class="token variable">$touches</span> <span class="token operator">=</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 comment" spellcheck="true">/**
* 獲取擁有此評論的文章。
*/</span>
<span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">post<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 this">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">belongsTo<span class="token punctuation">(</span></span><span class="token string">'App\Post'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre><p>現在,當你更新一個 Comment 時,它所屬的 Post 擁有的 <code class=" language-php">updated_at</code> 字段也會被同時更新,使其更方便的得知何時讓一個 <code class=" language-php">Post</code> 模型的緩存失效:</p><pre class=" language-php"><code class=" language-php"><span class="token variable">$comment</span> <span class="token operator">=</span> <span class="token scope">App<span class="token punctuation">\</span>Comment<span class="token punctuation">::</span></span><span class="token function">find<span class="token punctuation">(</span></span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$comment</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">text</span> <span class="token operator">=</span> <span class="token string">'Edit to this comment!'</span><span class="token punctuation">;</span>
<span class="token variable">$comment</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">save<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h2>譯者署名</h2><table><thead><tr><th>用戶名</th><th>頭像</th><th>職能</th><th>簽名</th></tr></thead><tbody><tr><td><a href="https://laravel-china.org/users/79">@skyverd</a></td><td><img class="avatar-66 rm-style" src="https://dn-phphub.qbox.me/uploads/avatars/79_1427370664.jpeg?imageView2/1/w/100/h/100"></td><td>翻譯</td><td>全桟工程師,<a href="https://skyverd.com">時光博客</a></td></tr></tbody></table></article>
- 入門指南
- 安裝
- 配置信息
- 文件夾結構
- 請求周期
- 開發環境部署
- Valet
- Homestead
- 核心概念
- 服務提供者
- Facades
- Contracts
- 服務容器
- HTTP 層
- 路由
- 中間件
- CSRF 保護
- 控制器
- 請求
- 響應
- 視圖
- Session
- 表單驗證
- 前端
- Blade 模板
- 本地化
- 前端指南
- 編輯資源 Mix
- 安全
- API 認證
- 用戶認證
- 用戶授權
- 加密解密
- 哈希
- 重置密碼
- 數據庫
- 快速入門
- 查詢構造器
- 分頁
- 數據庫遷移
- Redis
- 數據填充
- Eloquent ORM
- Eloquent ORM快速入門
- 模型關聯
- Eloquent 集合
- 修改器
- 序列化
- 綜合話題
- Artisan 命令行
- 廣播系統
- 緩存系統
- 集合
- 錯誤與日志
- 事件系統
- 文件存儲
- 輔助函數
- 郵件發送
- 消息通知
- 擴展包開發
- 隊列
- 任務調度