Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
10.2k views
in Technique[技术] by (71.8m points)

php - Deciphering a Stack Trace Error on "Remember Me" Function

I have received my first stack trace error on a PHP beginners CRUD educational project. Since I am a newbie, I am having trouble with it. After many hours of research I believe I may have narrowed down the error to my logout method, (although this is merely my opinion). If someone can help me correct my error I would greatly appreciate it. I will attach some of my code here. Since I am not exactly sure where the error lies, I may have left something out. If that is the case I am more than happy to supply more code. Thank you in advance.

My error occurs when I click the logout button;

Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error in C:xampphtdocsest_site.comclassesdb.php:51 Stack trace: #0 C:xampphtdocsest_site.comclassesdb.php(51): PDOStatement->fetchAll(5) #1 C:xampphtdocsest_site.comclassesdb.php(77): DB->query('DELETE FROM use...', Array) #2 C:xampphtdocsest_site.comclassesdb.php(90): DB->action('DELETE', 'users_session', Array) #3 C:xampphtdocsest_site.comclassesuser.php(243): DB->delete('users_session', Array) #4 C:xampphtdocsest_site.comlogout.php(5): User->logout() #5 {main} thrown in C:xampphtdocsest_site.comclassesdb.php on line 51

If I comment out this code;

 $this->_db->delete('users_session', array('user_id', '=', $this->data()->id)); 

I do not get the fatal error. However, I am unable to delete the entry that was made in the database to retain the hash for the 'remember me' cookie.

According to the stack trace error and everything that I have tried, I keep getting this line as some sort of problem.

 $this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);

I do not know why I am having an issue here. I know this error seems huge and unmanageable but I am hoping someone here has an eye for these stack trace problems and can help me with this issue. Thanks again.

enter code here
 /////////////////////////////////////////////////////////// 


  <?php     
     require_once 'corefiles/initiation.php';       

     if(Input::exists()) {
    if(Token::check(Input::get('token'))) {
        
        $validate = new Validate();
        $validation = $validate->check($_POST, array(
            'username' => array('required' => true),
            'password' => array('required' => true)
        ));
        
        if($validation->passed()) {
            $user = new User();
            
            $remember = (Input::get('remember') === 'on') ? true : false;                
            $login = $user->login(Input::get('username'), Input::get('password'), $remember);
            
            if($login) {
                Redirect::redirectto('index.php');                                  
            } else {
                echo '<p>Sorry, logging in failed.</p>';
            }
            
        } else {
            foreach($validation->errors() as $error) {
                echo $error, '<br>';
            }
        }           
    }
}


 <form action="" method="post">
   <div class="field">
       <label for="username">Username</label>
       <input type="text" name="username" id="username" autocomplete="off">
   </div>

   <div class="field">
       <label for="password">Password</label>
        <input type="password" name="password" id="password">   
   </div>   

   <div class="field">
      <label for="remember">
        <input type="checkbox" name="remember" id="remember"> Remember me
      </label>
    </div>

    <input type="hidden" name="token" value="<?php echo Token::generate(); ?>">
    <input type="submit" value="Log in">
 </form>

 ////////////////////////////////////////////////////////////
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 {
            $this->find($user);
        }
    }

     public function logout() { 
        // THIS LINE IS WHAT I BELIEVE IS THE PROBLEM. IF COMMENTED OUT I CAN LOGOUT HOWEVER
        // THE HASH IN THE DATABASE DOES NOT GET DELETED.               
        $this->_db->delete('users_session', array('user_id', '=', $this->data()->id));            
        Session::delete($this->_sessionName);
        Cookie::delete($this->_cookieName);           
    }

/////////////////////////////////////////////////////////////    
class DB {
    private static $_instance = null;
    private $_pdo = null,
            $_query = null,
            $_error = false,
            $_results = null,
            $_count = 0;
    
    public $debug = true;
    
    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'));
            
            if($this->debug) {
                $this->_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            }
                            
        } catch(PDOException $e) {
            die($this->debug ? $e->getMessage() : '');
        }           
    }
    public function query($sql, $params = array()) {
        $this->_error = false;
        if($this->_query = $this->_pdo->prepare($sql)) {                
            $x = 1;
            if(count($params)) {
                foreach($params as $param) {
                    $this->_query->bindValue($x, $param);
                    $x++;                       
                }                   
            }               
            
            if($this->_query->execute()){
                // THIS "FETCH" CODE MAY BE AN ISSUE AS WELL. 
                //$this->_results = $this->_query->fetchObject();
                $this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);//THIS IS db.php line 51
                
                
                $this->_count = $this->_query->rowCount();    
                
            } else {
                $this->_error = true;
            }
        }
        
        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} ?";
                
                if(!$this->query($sql, array($value))->error()) {
                    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);
    }


    /////////////////////////////////////////////////////
    //Logout script
        require_once 'core/init.php';       

        $user = new User();
        $user->logout();
         //var_dump( $user->logout() );

         //redirect script
        Redirect::redirectto('index.php');   

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You're doing a fetchAll after a delete query.

Try checking how many results are returned before calling fetchAll in the DB query method and see if that fixes the issue.

public function query($sql, $params = array()) {
    $this->_error = false;
    if($this->_query = $this->_pdo->prepare($sql)) {                
        $x = 1;
        if(count($params)) {
            foreach($params as $param) {
                $this->_query->bindValue($x, $param);
                $x++;                       
            }                   
        }               
        
        if($this->_query->execute()){
            if(substr($sql, 0, 6) === "SELECT"){
                $this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
            } else {
                 $this->_results = null;
            }  
            $this->_count = $this->_query->rowCount();
        } else {
            $this->_error = true;
        }
    }
    
    return $this;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...