Всем привет.
На одном сайте решил сделать разграничение прав доступа.
В принципе не сложно и самому написать, но получалось уж очень много все. И добавление прав и добавление групп...
Погуглив, набрел на готовое решение _http://net.tutsplus.com/tutorials/php/a-better-login-system/
Хоть статья там и большая... на деле там один файл с классом. Все остальное - формы управления. Именно "готовость" и повлияла на решение взять его.
По глупости начал внедрять сие дело к себе(уж очень понравилось управление всеми правами)... и потом решил проверить количество запросов... как не прискорбно, скрипт делает кучу запросов.
Методом "исследования", были выявлены места которые делают эти самые запросы.
С классами я на ВЫ, и переделать особо не получается.
Прошу помощи в оптимизации. Если у кого будет время, был бы признателен за помощь!
Теперь собственно сам класс
PHP:
скопировать код в буфер обмена
<?PHP class ACL { var $perms = array(); //Array : Stores the permissions for the user var $userID = 0; //Integer : Stores the ID of the current user var $userRoles = array(); //Array : Stores the roles of the current user function __constructor($userID = '') { if ($userID != '') { } else { $this->userID = floatval($_SESSION['userID']); } $this->userRoles = $this->getUserRoles('ids'); $this->buildACL(); } function ACL($userID = '') { $this->__constructor($userID); //crutch for PHP4 setups } function buildACL() { //first, get the rules for the user's role if (count($this->userRoles) > 0 ) { $this->perms = array_merge($this->perms,$this->getRolePerms($this->userRoles)); } //then, get the individual user permissions $this->perms = array_merge($this->perms,$this->getUserPerms($this->userID)); } function getPermKeyFromID($permID) { $strSQL = "SELECT `permKey` FROM `permissions` WHERE `ID` = " . floatval($permID) . " LIMIT 1"; return $row[0]; } function getPermNameFromID($permID) { $strSQL = "SELECT `permName` FROM `permissions` WHERE `ID` = " . floatval($permID) . " LIMIT 1"; return $row[0]; } function getRoleNameFromID($roleID) { $strSQL = "SELECT `roleName` FROM `roles` WHERE `ID` = " . floatval($roleID) . " LIMIT 1"; return $row[0]; } function getUserRoles() { $strSQL = "SELECT * FROM `user_roles` WHERE `userID` = " . floatval($this->userID) . " ORDER BY `addDate` ASC"; { $resp[] = $row['roleID']; } return $resp; } function getAllRoles($format='ids') { $strSQL = "SELECT * FROM `roles` ORDER BY `roleName` ASC"; { if ($format == 'full') { $resp[] = array("ID" => $row['ID'],"Name" => $row['roleName']); } else { $resp[] = $row['ID']; } } return $resp; } function getAllPerms($format='ids') { $strSQL = "SELECT * FROM `permissions` ORDER BY `permName` ASC"; { if ($format == 'full') { $resp[$row['permKey']] = array('ID' => $row['ID'], 'Name' => $row['permName'], 'Key' => $row['permKey']); } else { $resp[] = $row['ID']; } } return $resp; } function getRolePerms($role) { { $roleSQL = "SELECT * FROM `role_perms` WHERE `roleID` IN (" . implode(",",$role) . ") ORDER BY `ID` ASC"; } else { $roleSQL = "SELECT * FROM `role_perms` WHERE `roleID` = " . floatval($role) . " ORDER BY `ID` ASC"; } { $pK = strtolower($this->getPermKeyFromID($row['permID'])); if ($pK == '') { continue; } if ($row['value'] === '1') { $hP = true; } else { $hP = false; } $perms[$pK] = array('perm' => $pK,'inheritted' => true,'value' => $hP,'Name' => $this->getPermNameFromID($row['permID']),'ID' => $row['permID']); } return $perms; } function getUserPerms($userID) { $strSQL = "SELECT * FROM `user_perms` WHERE `userID` = " . floatval($userID) . " ORDER BY `addDate` ASC"; { $pK = strtolower($this->getPermKeyFromID($row['permID'])); if ($pK == '') { continue; } if ($row['value'] == '1') { $hP = true; } else { $hP = false; } $perms[$pK] = array('perm' => $pK,'inheritted' => false,'value' => $hP,'Name' => $this->getPermNameFromID($row['permID']),'ID' => $row['permID']); } return $perms; } function userHasRole($roleID) { foreach($this->userRoles as $k => $v) { { return true; } } return false; } function hasPermission($permKey) { { if ($this->perms[$permKey]['value'] === '1' || $this->perms[$permKey]['value'] === true) { return true; } else { return false; } } else { return false; } } function getUsername($userID) { $strSQL = "SELECT `username` FROM `users` WHERE `ID` = " . floatval($userID) . " LIMIT 1"; return $row[0]; } } ?>
Для праверки прав, в нужные страницы просто вставить
PHP:
скопировать код в буфер обмена
<?PHP $myACL = new ACL(); if ($myACL->hasPermission('access_admin') != true)// access_admin - группа, которой разрешен доступ на страницу { } ?>
В самом начал метод buildACL. В нем как я понял проверяется индивидуальная роль(по описанию) юзера и используется метод getRolePerms.
А вот этот самый метод getRolePerms в цикле гоняет getPermKeyFromID и зачем то getPermNameFromID(зачем получать название роли не понятно)
Оба этих метода getPermNameFromID и getPermKeyFromID получают имя и ключ прав доступа.
На выходе получаем кучу запросов на каждой странице. И как я понял, чем больше всяких прав и групп, тем больше будет запросов.
В идеале для таких дел максимум пару запросов, а не 10 или 15.
Кто бы помог оптимизировать данный скрипт. Думаю многим бы пригодился, так как удобен и прост в установке.
Скачать полный скрипт можно тут _http://d2o0t5hpnwv4c1.cloudfront.net/232_customSiteAccess/download.zip
|