Проблема с получением переменной из класса для проверки настроек разрешений

#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 or false , но затем проверяете, является ли это User or Admin , чего никогда не будет.

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 — да, это то, что я предлагаю.