使用预处理语句在mysqli中嵌套SELECT

时间:2016-01-01 19:07:01

标签: php mysql mysqli nested

我试图列出一个表来显示PHP应用程序中的用户权限。 我试图用MySQLi做,但在途中需要一些帮助。

我有这些桌子:

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

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

-------------------------------------
- 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>

1 个答案:

答案 0 :(得分:1)

不使用嵌套查询,而是在表之间使用一个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>';
}