#php #pdo #permissions
#php #pdo #разрешения
Вопрос:
Я пытаюсь выполнить оператор if, чтобы заполнить правильное меню навигации для пользователей с разными уровнями разрешений.
У меня есть класс под названием users, который имеет следующую функцию под названием ‘hasPermission’:
public function hasPermission($key) {
$group = $this->_db->get('groups', array('id', '=', $this->data()->group));
if($group->count()) {
$permissions = json_decode($group->first()->permissions, true);
if($permissions[$key] == true) {
return true;
}
}
return false;
}
Который обрабатывает следующие группы в моей базе данных:
Затем в другом файле я пытаюсь получить разрешение текущего пользователя на вход с помощью $permission
(я думаю, что здесь ошибка), а затем использовать оператор if для заполнения правильного файла.
$permission = $user->hasPermission($group);
if($permission == 'User') {
include 'nav/userNav.php';
} else if ($permission == 'Admin') {
include 'nav/adminNav.php';
}
Кто-нибудь видит, что я делаю неправильно?
Редактировать:
Полный код пользовательского класса:
<?php
class User {
private $_db,
$_data,
$_sessionName,
$_cookieName,
$_isLoggedIn;
public function __construct($user = null) {
$this->_db = DB::getInstance();
$this->_sessionName = Config::get('session/session_name');
$this->_cookieName = Config::get('remember/cookie_name');
if(!$user) {
if(Session::exists($this->_sessionName)) {
$user = Session::get($this->_sessionName);
if($this->find($user)) {
$this->_isLoggedIn = true;
} else {
// process Logout
}
}
} else {
$this->find($user);
}
}
public function update($fields = array(), $id = null) {
if(!$id amp;amp; $this->isLoggedIn()) {
$id = $this->data()->id;
}
if(!$this->_db->update('users', $id, $fields)) {
throw new Exception('There was a problem updating!');
}
}
public function create($fields = array()) {
if(!$this->_db->insert('users', $fields)) {
throw new Exception('There was a problem creating an account:' . $this->_db->errorMessage());
}
$this->lastId = $this->_db->lastInsertId();
}
public function find($user = null) {
if($user) {
$field = (is_numeric($user)) ? 'id' : 'username';
$data = $this->_db->get('users', array($field, '=', $user));
if($data->count()) {
$this->_data = $data->first();
return true;
}
}
return false;
}
public function login($username = null, $password = null, $remember = false) {
if(!$username amp;amp; !$password amp;amp; $this->exists()) {
Session::put($this->_sessionName, $this->data()->id);
} else {
$user = $this->find($username);
if($user) {
if($this->data()->password === Hash::make($password, $this->data()->salt)) {
//if(Auth::check($this->data()->password, $password)){
Session::put($this->_sessionName, $this->data()->id);
if($remember) {
$hash = Hash::unique();
$hashCheck = $this->_db->get('users_session', array('user_id', '=', $this->data()->id));
if(!$hashCheck->count()) {
$this->_db->insert('users_session', array(
'user_id' => $this->data()->id,
'hash' => $hash
));
} else {
$hash = $hashCheck->first()->hash;
}
Cookie::put($this->_cookieName, $hash, Config::get('remember/cookie_expiry'));
}
return true;
}
}
}
return false;
}
public function hasPermission($key) {
$group = $this->_db->get('groups', array('id', '=', $this->data()->group));
if($group->count()) {
$permissions = json_decode($group->first()->permissions, true);
if($permissions[$key] == true) {
return true;
}
}
return false;
}
public function exists() {
return (!empty($this->_data)) ? true : false;
}
public function logout() {
$this->_db->delete('users_session', array('user_id', '=', $this->data()->id));
Session::delete($this->_sessionName);
Cookie::delete($this->_cookieName);
}
public function data() {
return $this->_data;
}
public function isLoggedIn() {
return $this->_isLoggedIn;
}
}
?>
ПРАВКА # 2 — Попытка создать новую функцию для этого:
public function getGroup($groupkey) {
$group_name = $this->_db->get('groups', array('name'));
}
Затем в другом файле, где я пытаюсь вызвать это:
$permission = $user->getGroup($group_name);
if($permission == 'User') {
include 'nav/userNav.php';
} else if ($permission == 'Admin') {
include 'nav/adminNav.php';
}
Правка # 3
С помощью этого кода:
public function getGroup($groupkey) {
$group_name = $this->_db->get('groups', array('name'));
return $group_name;
}
Я получаю эту ошибку:
Fatal error: Uncaught ArgumentCountError: Too few arguments to function User::getGroup(), 0 passed in /home/house/public_html/admin/index.php on line 322 and exactly 1 expected in /home/house/public_html/classes/User.php:116 Stack trace: #0 /home/house/public_html/admin/index.php(322): User->getGroup() #1 {main} thrown in
Функция действия в классе DB.
public function action($action, $table, $where = array()){
if(count($where) === 3){
$operators = array('=', '>', '<', '>=', '<=');
$field = $where[0];
$operator = $where[1];
$value = $where[2];
if(in_array($operator, $operators)) {
$sql = "{$action} FROM {$table} WHERE {$field} {$operator} ?";
$date = new DateTime();
file_put_contents('debug_log', "n[{$date->format('Y-m-d H:i:s')}] $sql", FILE_APPEND);
$results = $this->query($sql, array($value));
file_put_contents('debug_log1', "n[{$date->format('Y-m-d H:i:s')}] $sql" . print_r($results, 1), FILE_APPEND);
return $this;
}
}
return false;
}
РЕДАКТИРОВАТЬ — ПОЛНЫЙ КЛАСС DB
<?php
class DB {
private static $_instance = null;
private $_pdo,
$_query,
$_error = false,
$_results,
$_count = 0,
$_errmsg = "";
private function __construct(){
try {
$this->_pdo = new PDO('mysql:host=' . Config::get('mysql/host') . ';dbname=' . Config::get('mysql/db'), Config::get('mysql/username'), Config::get('mysql/password'));
/*$host = config::get('mysql/host');
$database = config::get('mysql/db');
$username = config::get('mysql/user');
$password = config::get('mysql/password');
$dbh = new PDO('mysql:host='.$host.';dbname='.$database.', $username, $password);*/
} catch(PDOException $e) {
die($e->getMEssage());
}
}
//**********LastID
public function lastInsertId () {
return $this->_pdo->lastInsertId();
}
public static function getInstance() {
if(!isset(self::$_instance)) {
self::$_instance = new DB();
}
return self::$_instance;
}
public function query($sql, $params = array()){
"DEBUG DB::query called<br>SQL: $sql<br><br>PARAMS: " . implode("<br>", $params) . "<hr>n";
$this->_error = false;
if($this->_query = $this->_pdo->prepare($sql)) {
"DEBUG: prepared statement created ok<hr>n";
$x = 1;
if(count($params)){
foreach($params as $param){
$this->_query->bindValue($x, $param);
$x ;
}
}
if($this->_query->execute()){
$this->_results = $this->_query->fetchALL(PDO::FETCH_OBJ);
$this->_count = $this->_query->rowCount();
"DEBUG: query succeeded, rowcount was: " . $this->_count . "<hr>n";
} else {
"DEBUG: query failed to execute, reason:<br>" . implode( "<br>", $this->_query->errorInfo() ) . "<hr>n";
$this->_error = true;
}
} else {
"DEBUG: Failed to create prepared statement<hr>n";
}
return $this;
}
public function action($action, $table, $where = array()){
if(count($where) === 3){
$operators = array('=', '>', '<', '>=', '<=');
$field = $where[0];
$operator = $where[1];
$value = $where[2];
if(in_array($operator, $operators)) {
$sql = "{$action} FROM {$table} WHERE {$field} {$operator} ?";
$date = new DateTime();
file_put_contents('debug_log', "n[{$date->format('Y-m-d H:i:s')}] $sql", FILE_APPEND);
$results = $this->query($sql, array($value));
file_put_contents('debug_log1', "n[{$date->format('Y-m-d H:i:s')}] $sql" . print_r($results, 1), FILE_APPEND);
return $this;
}
}
return false;
}
public function get($table, $where){
return $this->action('SELECT *', $table, $where);
}
public function delete($table, $where){
return $this->action('DELETE', $table, $where);
}
public function insert($table, $fields = array()) {
$keys = array_keys($fields);
$values = '';
$x = 1;
foreach($fields as $field) {
$values .= '?';
if($x < count($fields)) {
$values .= ', ';
}
$x ;
}
$sql = "INSERT INTO {$table} (`" . implode('`, `', $keys) . "`) Values ({$values})";
return ! $this-> query($sql, $fields)->error();
}
public function update($table, $id, $fields) {
$set = '';
$x = 1;
foreach($fields as $name => $value) {
$set .= "{$name} = ?";
if($x < count($fields)) {
$set .= ', ';
}
$x ;
}
$sql = "UPDATE {$table} SET {$set} WHERE id = {$id}";
return ! $this-> query($sql, $fields)->error();
}
public function results() {
return $this->_results;
}
public function first() {
return $this->results()[0];
}
public function error() {
return $this->_error;
}
public function errorMessage() {
return $this->_errmsg;
}
public function count(){
return $this->_count;
}
}
?>
Комментарии:
1. Почему вы храните разрешения в виде объекта JSON?
2.
$permission = 'User'
будет ли присвоение значения$permission == 'User'
означать проверку, если оно равно.3. Вы возвращаете
true
orfalse
, но затем проверяете, является ли этоUser
orAdmin
, чего никогда не будет.4. Добавьте новый метод с именем
getGroup()
(или что-то подобное) и реализуйте его там. Не пытайтесь делать это подhasPermission
; это должно возвращать только логическое значение.5. Добавлен класс @waterloomatt DB. У пользователя может быть только одна роль.
Ответ №1:
Основываясь на обновленной информации, я вижу, что вы используете PDO и выполняете fetchALL
и возвращаете результаты в виде массива объектов stdClass ( FETCH_OBJ
). Не уверен, зачем вы вообще сохраняете permission
, не говоря уже о том, чтобы как объект JSON, но, к счастью, нам не нужен этот столбец в данном случае. Мы можем просто посмотреть, name
основываясь на id
.
Важно понимать, что $this->_db->get(...
возвращает экземпляр вашего класса DB (или false
), поэтому вы должны назвать свою переменную соответствующим образом, $db
. Дайте мне знать, если у вас возникнут какие-либо проблемы, и я постараюсь помочь.
<?php
/**
* Returns the role name of the currently logged in user. If no role can be
* determined, an empty string will be returned.
* @return string
*/
public function getGroup()
{
$role = '';
// I really can't tell what `$this->data()->group` is but
// I'm making the assumption that it is the logged in user's role ID.
$db = $this->_db->get('groups', array('id', '=', $this->data()->group));
if($db->count() > 0) {
// `first()` returns the first element of the results as a stdClass object.
// https://www.geeksforgeeks.org/what-is-stdclass-in-php/
$role = $db->first()->name;
}
return $role;
}
Ответ №2:
...
public function hasPermission($key) {
$group = $this->_db->get('groups', array('id', '=', $this->data()->group));
if($group->count()) {
$permissions = json_decode($group->first()->permissions, true);
if($permissions[$key] == true) {
return $key;//change true here to the role
}
}
return false;
}
...
Комментарии:
1. Однако какова была бы роль?
2. Я бы не стал делать это таким образом. Название
hasPermission
подразумевает, что метод вернет логическое значение или, по крайней мере, что-то похожее на логическое значение.3. @waterloomatt если вы придерживаетесь этого, то вам придется создать отдельную функцию, например,
function getPermission()
для восстановления разрешения на ее использование4. @Paul роль — это группа, которая была возвращена из базы данных, я поместил комментарий так, как я понял сценарий
5. @auwalup — да, это то, что я предлагаю.