# 多對多關聯
## 關聯定義
例如,我們的用戶和角色就是一種多對多的關系,我們在`User`模型定義如下:
~~~
<?php
namespace app\model;
use think\Model;
class User extends Model
{
public function roles()
{
return $this->belongsToMany(Role::class, 'UserRole', 'role_id', 'user_id');
}
}
~~~
`belongsToMany`方法的參數如下:
> ### belongsToMany('關聯模型','中間表','外鍵','關聯鍵');
* **關聯模型**(必須):關聯模型類名,Role 或者 Role::class
* **中間表模型**:默認的表名是當前模型名+`_`+關聯模型名 (可自定義)
* **外鍵**:中間表的當前模型外鍵,默認的外鍵名規則是關聯模型名+`_id`
* **關聯鍵**:中間表的當前模型關聯鍵名,默認規則是當前模型名+`_id`
中間表名無需添加表前綴,并支持定義中間表模型,例如:
~~~
public function roles()
{
return $this->belongsToMany(Role::class, Access::class);
}
~~~
中間表模型類必須繼承`think\model\Pivot`,例如:
~~~
<?php
namespace app\model;
use think\model\Pivot;
class Access extends Pivot
{
protected $autoWriteTimestamp = 'datetime';
}
~~~
中間表模型的基類`Pivot`默認關閉了時間戳自動寫入,上面的中間表模型則開啟了時間戳字段自動寫入。
## 關聯查詢
我們可以通過下面的方式獲取關聯數據
~~~
$user = UserModel::find(1);
pr($user->toArray());
// 獲取用戶的所有角色
$roles = [];
foreach ($user->roles as $role) {
$roles[] = $role->name;
// 獲取中間表模型
pr($role->pivot->toArray());
}
pr($roles);
~~~
## 關聯新增
~~~
$user = User::find(1);
// 給用戶增加管理員權限 會自動寫入角色表和中間表數據
$user->roles()->save(['name'=>'管理員']);
// 批量授權
$user->roles()->saveAll([
['name'=>'管理員'],
['name'=>'操作員'],
]);
~~~
只新增中間表數據(角色已經提前創建完成),可以使用
~~~
$user = User::find(1);
// 僅增加管理員權限(假設管理員的角色ID是1)
$user->roles()->save(1);
// 或者
$role = Role::find(1);
$user->roles()->save($role);
// 批量增加關聯數據
$user->roles()->saveAll([1,2,3]);
~~~
單獨更新中間表數據,可以使用:
~~~
$user = User::find(1);
// 增加關聯的中間表數據
$user->roles()->attach(1);
// 傳入中間表的額外屬性
$user->roles()->attach(1,['remark'=>'test']);
// 刪除中間表數據
$user->roles()->detach([1,2,3]);
~~~
> `attach`方法的返回值是一個`Pivot`對象實例,如果是附加多個關聯數據,則返回`Pivot`對象實例的數組。
其他方法
public function save($data, array $pivot = \[\])
public function saveAll(iterable $dataSet, array $pivot = \[\], bool $samePivot = false)
public function attach($data, array $pivot = \[\])
public function attached($data)
public function detach($data = null, bool $relationDel = false): int
public function sync(array $ids, bool $detaching = true): array
~~~
public function update() {
// $data = [1,2];
$data = [1=>['memo' => 'read'], 2=>['memo' => 'write']];
$user = UserModel::find(1);
//$user->roles()->sync([1,3]);
$user->roles()->sync($data);
}
~~~
- 搭建ThinkPHP6的開發環境
- 配置ThinkPHP6
- 必要的基礎知識(basic)
- MVC開發模式
- 控制器(controller)
- 數據庫(database)
- 模型(model)
- 模型關聯(relation)
- 視圖(view)
- Session
- Cookie
- 緩存(cache)
- 上傳(upload)
- 驗證器(validate)
- 驗證碼(captcha)
- 命令行(command)
- 服務器部署(deploy)
- 數據備份(backup)
- 數據同步(synchronization)
- 訂閱服務(subscribe)
- PHP 易混淆知識點
- 助手函數
- MySQL規范
- Redis 規范
- office插件 phpoffice
- 拼音插件 pinyin
- 日期插件 datetime
- 消息插件 amqp
- 產品部署環境的搭建
- PDF 等雜項處理
- 文件上傳
- 常用擴展
- flc/dysms
- 使用示例 ①
- 使用示例 ②
- qiniu/php-sdk
- 簡介
- 使用示例
- 使用示例 2 ②
- liliuwei/thinkphp-jump
- 擴展介紹
- 下載擴展
- 使用方法
- topthink/think-captcha
- 安裝擴展
- 驗證碼顯示
- 更換驗證碼
- 驗證碼校驗
- 驗證碼配置
- 自定義驗證碼
- phpoffice/phpspreadsheet
- 數據寫入表格
- 讀取表格數據
- topthink/think-queue
- 安裝
- 自定義函數
- 任務類
- 帶有日志的任務類