简体   繁体   中英

Is there a smarter way to load many-to-many relationships with PHP and MySQL?

Say you have Users and Roles in a many-to-many relationship. Standard setup with following tables:

user            role           user_role
  user_id         role_id        user_id
  email           name           role_id

Preferably with as few queries as possible, what's a good way to load all users with all tags belonging to them? That is, I'd like to end up with users, each having an array of roles.


I'm currently thinking of using the following, which'll requires two queries.

  1. Get all users with group concatenated role ids.
  2. Get all role names in separate query
  3. Loop through users, explode role ids and connect them with names from role query as we go.

Any good/better/more efficient/cleaner/quicker alternatives? Any good way to do this in a single query?

To return all roles for all users

<?php
    $array=array();
    $sql='SELECT user.email,role.name
    FROM user
    INNER JOIN user_role ON user_role.user_id=user.user_id
    INNER JOIN role ON user_role.role_id=role.role_id';

    $stmt = db::db()->query($sql);
    while($row=$stmt->fetch(PDO::FETCH_ASSOC))
    {
        if (!isset($array[$row['email']])){$array[$row['email']]=array();}
        array[$row['email']][]=$row['name'];
    }

?>

To return all roles for a single user

<?php
    $sql='SELECT user.email,role.name
    FROM user
    INNER JOIN user_role ON user_role.user_id=user.user_id
    INNER JOIN role ON user_role.role_id=role.role_id
    WHERE user.email=?';

    $stmt = db::db()->prepare($sql);
    $stmt->execute(array('anEmail@domain.com'));
    $roles=$stmt->fetchAll(PDO::FETCH_ASSOC);
?>

The above assumes that all users have at least one role. If not, use outer joins.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM