使用准备好的语句在 mysqli 中嵌套 SELECT

Nested SELECT in mysqli with prepared statements

我正在尝试列出 table 以在 PHP 应用程序中显示用户权限。 我正在尝试使用 MySQLi 来完成它,但在途中需要一些帮助。

我有这些 tables:

tblUsers(userID PK, username)
tblUsersRoles (roleID PK, roleName)
tblUsersPermission (permissionID PK, permissionName)
tblUsersUserRole (userID FK, roleID FK)
tblUsersRolesPermissions (roleID FK, permissionID FK)

我想为每个用户显示这样的 table:

-------------------------------------
- RoleName     - PermissionName     -
-------------------------------------
- Admin        - Edit profile       -
-              - Edit permissions   -
-              - Create invoice     -
-------------------------------------
- UserAdmin    - Add user           -
-              - Edit user          -
-              - Delete user        -
-------------------------------------

这怎么可能?我已经尝试使用嵌套的准备好的语句,但只会出现我不知道如何修复自己的错误。有人可以帮忙吗?

在我阅读之后它与 store_result() 有一些关系,但我似乎无法掌握它...

到目前为止我的代码是这样的:

    <table class="table table-striped">
    <tr>
        <th>RoleName</th>
        <th>PermissionName</th>
    </tr>
    <?php
        //Get roles where the user is a member from tblUsersUserRoles
        $userID = $_SESSION['userID'];
        $table = DBPREFIX.'tblUsersUserRoles UR, '.DBPREFIX.'tblUsersRoles R';
        $query = "SELECT UR.roleID, R.roleName FROM $table WHERE R.roleID = UR.roleID AND UR.userID=? ORDER BY UR.roleID";
        $statement = $mysqli->prepare($query);
        $statement->bind_param('i', $userID);
        $statement->execute();
        $statement->bind_result($roleID, $roleName);

        while($statement->fetch()) {
            echo '<tr>';
            echo '<td>'.$roleName.'</td>';
            echo '<td></td>';
            echo '</tr>';


            //Get permissions for this role
            $table2 = DBPREFIX.'tblUsersPermissions P, '.DBPREFIX.'tblUsersRolesPermissions RP';
            $query2 = "SELECT P.permissionName FROM $table2 WHERE P.permissionID = RP.permissionID AND RP.roleID=? ORDER BY P.permissionGroup";
            $statement2 = $mysqli->prepare($query2);
            $statement2->bind_param('i', $roleID);
            $statement2->execute();
            $statement2->bind_result($permissionName);

            while($statement2->fetch()) {
                echo '<tr>';
                echo '<td></td>';
                echo '<td>'.$permissionName.'</td>';
                echo '</tr>';
            }
            $statement2->close();
        }   
        $statement->close();

    ?>
</table>

不使用嵌套查询,而是在表之间使用一个带有 JOIN 的查询。

$query = "SELECT UR.roleID, R.roleName, P.permissions
          FROM ".DBPREFIX."tblUsersUserRoles UR
          JOIN ".DBPREFIX."tblUsersRoles R ON R.roleID = UR.roleID
          LEFT JOIN ".DBPREFIX."tblUsersRolesPermissions RP ON RP.roleID = R.roleID
          LEFT JOIN ".DBPREFIX."blUsersPermissions P ON P.permissionID = RP.permissionID
          WHERE UR.userID = ?
          ORDER BY UR.roleID, P.permissionGroup";
    $statement = $mysqli->prepare($query);
    $statement->bind_param('i', $userID);
    $statement->execute();
    $statement->bind_result($roleID, $roleName, $permissionName);

然后当您处理结果时,您会在角色名称行发生变化时显示它。

$lastRoleID = null;

while ($statement->fetch()) {
    if ($roleID != $lastRoleID) {
        echo '<tr>';
        echo '<td>'.$roleName.'</td>';
        echo '<td></td>';
        echo '</tr>';
        $lastRoleID = $roleID;
    }
    echo '<tr>';
    echo '<td></td>';
    echo '<td>'.$permissionName.'</td>';
    echo '</tr>';
}