成人精品一区二区三区中文字幕-成人精品一区二区三区-成人精品一级毛片-成人精品亚洲-日本在线视频一区二区-日本在线视频免费

導航首頁 ? 技術教程 ? PHP laravel中的多對多關系實例詳解
全站頭部文字 我要出現在這里
PHP laravel中的多對多關系實例詳解 705 2024-01-11   

數據表之間是縱橫交叉、相互關聯的,laravel的一對一,一對多比較好理解,官網介紹滴很詳細了,在此我就不贅述啦,重點我記下多對多的關系

一種常見的關聯關系是多對多,即表A的某條記錄通過中間表C與表B的多條記錄關聯,反之亦然。比如一個用戶有多種角色,反之一個角色對應多個用戶。

為了測試該關聯關系,我們沿用官網的用戶角色示例:

需要三張數據表:users、roles 和 role_user,role_user 表按照關聯模型名的字母順序命名(這里role_user是中間表),并且包含 user_id 和 role_id兩個列。

多對多關聯通過編寫返回 belongsToMany 方法返回結果的方法來定義。廢話不說多,直接上數據結構:

1:創建一個角色表roles,并添加一些初始化數據:

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
`remember_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES ('1', 'admin', 'admin@163.com', '$2y$10$J/yXqscucanrHAGZp9G6..Tu1Md.SOljX3M8WrHsUdrgat4zeSuhC', 'ilocXtjZJwhrmIdLG1cKOYegeCwQCkuyx1pYAOLuzY2PpScQFT5Ss7lBCi7i', '2016-04-21 16:26:23', '2016-12-14 09:29:59');
INSERT INTO `users` VALUES ('2', 'baidu', '10940370@qq.com', '$2y$10$2A5zJ4pnJ5uCp1DN3NX.5uj/Ap7P6O4nP2BaA55aFra8/rti1K6I2', null, '2016-04-22 06:48:10', '2016-04-22 06:48:10');
INSERT INTO `users` VALUES ('3', 'fantasy', '1009@qq.com', '', null, '2017-06-14 10:38:57', '2017-06-15 10:39:01');

2:創建一個角色表roles,并添加一些初始化數據:

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for roles
-- ----------------------------
DROP TABLE IF EXISTS `roles`;
CREATE TABLE `roles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-- ----------------------------
-- Records of roles
-- ----------------------------
INSERT INTO `roles` VALUES ('1', '超級版主', '2016-04-21 16:26:23', '2016-12-14 09:29:59');
INSERT INTO `roles` VALUES ('2', '司令', '2016-04-22 06:48:10', '2016-04-22 06:48:10');
INSERT INTO `roles` VALUES ('3', '軍長', '2017-06-14 10:38:57', '2017-06-15 10:39:01');
INSERT INTO `roles` VALUES ('4', '司長', '2017-06-07 10:41:41', '2017-06-15 10:41:51');
INSERT INTO `roles` VALUES ('5', '團戰', '2017-06-22 10:41:44', '2017-06-28 10:41:54');
INSERT INTO `roles` VALUES ('6', '小兵', '2017-06-22 10:41:47', '2017-06-22 10:41:56');

3:創建一個中間表role_user用于記錄users表與roles表的對應關系,并添加一些初始化數據:

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for role_user
-- ----------------------------
DROP TABLE IF EXISTS `role_user`;
CREATE TABLE `role_user` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `user_id` int(11) DEFAULT NULL,
 `role_id` int(11) DEFAULT NULL,
 `created_at` datetime DEFAULT NULL,
 `updated_at` datetime DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of role_user
-- ----------------------------
INSERT INTO `role_user` VALUES ('1', '1', '2', '2017-06-07 11:42:13', '2017-06-21 11:32:16');
INSERT INTO `role_user` VALUES ('2', '1', '3', '2017-06-07 11:32:13', '2017-06-07 11:22:13');
INSERT INTO `role_user` VALUES ('3', '2', '4', '2017-06-07 11:32:13', '2017-06-07 11:12:13');
INSERT INTO `role_user` VALUES ('4', '1', '5', '2017-06-07 11:32:13', '2017-06-07 11:22:13');
INSERT INTO `role_user` VALUES ('5', '3', '6', '2017-06-07 11:32:13', '2017-06-07 11:52:13');
INSERT INTO `role_user` VALUES ('6', '3', '2', '2017-06-07 11:32:13', '2017-06-07 11:42:13');
INSERT INTO `role_user` VALUES ('7', '2', '2', '2017-06-07 11:42:13', '2017-06-07 11:52:13');

注意我們定義中間表的時候沒有在結尾加s并且命名規則是按照字母表順序,將role放在前面,user放在后面,并且用_分隔,這一切都是為了適應Eloquent模型關聯的默認設置:在定義多對多關聯的時候如果沒有指定中間表,Eloquent默認的中間表使用這種規則拼接出來。

創建一個Role模型:

<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
/**
 * Class Role
 * @package AppModels
 * @mixin Eloquent
 */
class Role extends Model
{
}

然后我們在 User 模型上定義 roles 方法:

<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
/**
 * Class User
 * @package AppModels
 * @mixin Eloquent
 */
class User extends Model
{
  /**
   * 用戶角色
   */
  public function roles()
  {
    return $this->belongsToMany('AppModelsRole');
  }
}

注:正如我們上面提到的,如果中間表不是role_user,那么需要將中間表作為第二個參數傳入belongsToMany方法,如果中間表中的字段不是user_id和role_id,這里我們姑且將其命名為$user_id和$role_id,那么需要將$user_id作為第三個參數傳入該方法,$role_id作為第四個參數傳入該方法,如果關聯方法名不是roles還可以將對應的關聯方法名作為第五個參數傳入該方法。

接下來我們在控制器中編寫測試代碼:

<?php
$user = User::find(1);
$roles = $user->roles;
echo '用戶'.$user->name.'所擁有的角色:';
foreach($roles as $role)
  echo $role->name.' '; //對應輸出為:用戶admin所擁有的角色:司令 軍長 團戰 

當然,和所有其它關聯關系類型一樣,你可以調用roles 方法來添加條件約束到關聯查詢上:

User::find(1)->roles()->orderBy('name')->get();

正如前面所提到的,為了確定關聯關系連接表的表名,Eloquent 以字母順序連接兩個關聯模型的名字。不過,你可以重寫這種約定 —— 通過傳遞第二個參數到 belongsToMany 方法:

return $this->belongsToMany('AppModelsRole', 'user_roles');

除了自定義連接表的表名,你還可以通過傳遞額外參數到 belongsToMany 方法來自定義該表中字段的列名。第三個參數是你定義關聯關系模型的外鍵名稱,第四個參數你要連接到的模型的外鍵名稱:

return $this->belongsToMany('AppModelsRole', 'user_roles', 'user_id', 'role_id');

定義相對的關聯關系

要定義與多對多關聯相對的關聯關系,只需在關聯模型中調用一下 belongsToMany 方法即可。我們在 Role 模型中定義 users 方法:

<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
/**
 * Class Role
 * @package AppModels
 * @mixin Eloquent
 */
class Role extends Model
{
  /**
   * 角色用戶
   */
  public function users()
  {
    return $this->belongsToMany('AppModelsUser');
  }
}

正如你所看到的,定義的關聯關系和與其對應的User 中定義的一模一樣,只是前者引用 AppModelsRole,后者引用AppModelsUser,由于我們再次使用了 belongsToMany 方法,所有的常用表和鍵自定義選項在定義與多對多相對的關聯關系時都是可用的。

測試代碼如下:

$role = Role::find(2);
$users = $role->users;
echo '角色#'.$role->name.'下面的用戶:';
foreach ($users as $user) 
  echo $user->name.' ';//對應輸出為:角色#司令下面的用戶:admin fantasy baidu

正如你看到的,處理多對多關聯要求一個中間表。Eloquent 提供了一些有用的方法來與這個中間表進行交互,例如,我們假設 User 對象有很多與之關聯的 Role 對象,訪問這些關聯關系之后,我們可以使用這些模型上的pivot 屬性訪問中間表字段:

$roles = User::find(1)->roles;
foreach ($roles as $role) 
  echo $role->pivot->role_id.'<br>';//對應輸出為:2 3 5

注意我們獲取到的每一個 Role 模型都被自動賦上了 pivot 屬性。該屬性包含一個代表中間表的模型,并且可以像其它 Eloquent 模型一樣使用。

默認情況下,只有模型主鍵才能用在 pivot 對象上,如果你的 pivot 表包含額外的屬性,必須在定義關聯關系時進行指定:

return $this->belongsToMany('AppModelsRole')->withPivot('column1', 'column2');

比如我們修改role_user表增加一個字段 username 數據如下:

查看圖片

修改模型User:

<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
/**
 * Class User
 * @package AppModels
 * @mixin Eloquent
 */
class User extends Model
{
  /**
   * 用戶角色
   */
  public function roles()
  {
    //return $this->belongsToMany('AppModelsRole');
    return $this->belongsToMany('AppModelsRole')->withPivot('username');
  }
}

測試代碼如下:

$user = User::find(1);
foreach ($user->roles as $role) 
  echo $role->pivot->username;//對應輸出為:馬特馬特2馬特3

如果你想要你的 pivot 表自動包含created_at 和 updated_at 時間戳,在關聯關系定義時使用 withTimestamps 方法:

return $this->belongsToMany('AppModelsRole')->withTimestamps();

通過中間表字段過濾關聯關系

你還可以在定義關聯關系的時候使用 wherePivot 和 wherePivotIn 方法過濾belongsToMany 返回的結果集:

return $this->belongsToMany('AppModelsRole')->withPivot('username')->wherePivot('username', '馬特2');
//return $this->belongsToMany('AppModelsRole')->wherePivotIn('role_id', [1, 2]);

測試代碼如下:

$user = User::find(1);
print_r($user->roles->toArray());

以上對應輸出:

Array
(
  [0] => Array
    (
      [id] => 3
      [name] => 軍長
      [created_at] => 2017-06-14 10:38:57
      [updated_at] => 2017-06-15 10:39:01
      [pivot] => Array
        (
          [user_id] => 1
          [role_id] => 3
          [username] => 馬特2
        )
    )
)

如果你想要你的pivot表自動包含created_at和updated_at時間戳,在關聯關系定義時使用withTimestamps方法:

return $this->belongsToMany('AppModelsRole')->withTimestamps();

以上所述是小編給大家介紹的PHP laravel中的多對多關系實例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對綠夏網網站的支持!



主站蜘蛛池模板: 寰宇地理| 激情戏车震| 电影处女地| 千山暮雪演员表| 《暗恋电影》在线观看| 美少女巡逻队| bobo视频| 正在行动| 柿柿红红岁岁年电视剧演员表| 新红楼梦惊艳版| 在线观看www视频| 向退休生活游戏正版赚钱入口| 婷婷sese| 心跳源计划演员表| 美女mm免费视频| 佩佩猪| 甜蜜高潮 第一季 电视剧| 打开双腿扒开打屁股羞辱惩罚视频| 阿妹的诺言| 贪玩的小水滴300字| 故事电影| 八哥图库图谜| 伦理电影在线看| 林书宇| 浙江卫视节目表 今晚| 黎明电影| 下巴有个凹陷| 秦皇岛电视台| 富士变频器使用说明书| 寡妇一级毛片免费看| 董璇惊艳写真| 美丽的坏女人中文字幕| bitch| 亲密 电影| 家书1000字| 寡妇一级毛片视频| 纳尼亚传奇4在线观看免费完整版| 一半海水一半火焰免费观看| 看黄色录像播放| 夜之女王 电影| 自拍在线观看|

!!!站長長期在線接!!!

網站、小程序:定制開發/二次開發/仿制開發等

各種疑難雜癥解決/定制接口/定制采集等

站長微信:lxwl520520

站長QQ:1737366103