Php 解读“上的堆栈跟踪错误”;“记住我”;作用

Php 解读“上的堆栈跟踪错误”;“记住我”;作用,php,mysql,oop,Php,Mysql,Oop,我在一个PHP初学者CRUD教育项目中收到了我的第一个堆栈跟踪错误。因为我是个新手,所以我在这方面遇到了麻烦。经过数小时的研究,我相信我可能已经缩小了注销方法的错误范围(尽管这只是我的观点)。如果有人能帮我改正错误,我将不胜感激。我将在这里附上我的一些代码。因为我不确定错误在哪里,我可能遗漏了一些东西。如果是这样的话,我非常乐意提供更多的代码。先谢谢你 单击注销按钮时出现错误 致命错误:未捕获PDOException:SQLSTATE[HY000]:中的常规错误 C:\xampp\htdocs\

我在一个PHP初学者CRUD教育项目中收到了我的第一个堆栈跟踪错误。因为我是个新手,所以我在这方面遇到了麻烦。经过数小时的研究,我相信我可能已经缩小了注销方法的错误范围(尽管这只是我的观点)。如果有人能帮我改正错误,我将不胜感激。我将在这里附上我的一些代码。因为我不确定错误在哪里,我可能遗漏了一些东西。如果是这样的话,我非常乐意提供更多的代码。先谢谢你

单击注销按钮时出现错误


致命错误:未捕获PDOException:SQLSTATE[HY000]:中的常规错误 C:\xampp\htdocs\test_site.com\classes\db.php:51堆栈跟踪:#0 C:\xampp\htdocs\test\u site.com\classes\db.php(51): PDO语句->fetchAll(5)#1 C:\xampp\htdocs\test\u site.com\classes\db.php(77):db->query('DELETE 来自使用…',数组)#2 C:\xampp\htdocs\test\u site.com\classes\db.php(90):db->action('DELETE'), “用户会话”,数组)3 C:\xampp\htdocs\test\u site.com\classes\user.php(243): DB->delete('users_session',Array)#4 C:\xampp\htdocs\test_site.com\logout.php(5):User->logout()#5{main} 在第51行的C:\xampp\htdocs\test\u site.com\classes\db.php中抛出

如果我注释掉这个代码

 $this->_db->delete('users_session', array('user_id', '=', $this->data()->id)); 
我没有得到致命的错误。但是,我无法删除在数据库中创建的条目,以保留“记住我”cookie的哈希值

根据堆栈跟踪错误和我尝试过的一切,我一直认为这行是某种问题

 $this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
我不知道为什么我在这里有问题。我知道这个错误看起来很大而且难以管理,但我希望这里有人能关注这些堆栈跟踪问题,并能帮助我解决这个问题。再次感谢

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');   
在此处输入代码
/////////////////////////////////////////////////////////// 

在删除查询之后,您正在执行
fetchAll

在DB查询方法中调用fetchAll之前,请尝试检查返回的结果数量,看看这是否解决了问题

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;
}
您的“致命错误”是一个“未捕获的PDO异常”。这就是PDO代码应该包装在一个块中。为方便起见,您只需将每个PDO调用放入
try{…}
包装器中,然后按如下方式捕获:

try {
    /* Or whatever DB call you make */ 
    $this->_db->delete('users_session', array('user_id', '=', $this->data()->id)); 
} 
catch(\Exception $ex){
    error_log("An Exception was caught! :".print_r($ex,true));
}
通常最简单的方法是像上面的例子那样简单地放置一个catch-all全局异常(
\Exception
),而不是大量不同的特定异常,但是代码中有一个选项,只要您更熟悉这个概念

当某个操作(例如删除)失败时,这将为您提供基本反馈,以及失败的原因(在本例中写入PHP错误日志)

这不会解决核心问题(),但会停止生成致命错误并中断应用程序。然后,您可以更恰当地处理此问题,例如向用户输出消息


在如何在PHP中实现有效的异常处理方面,有很多有用的背景和结构。

Hello@Jay Hewitt,感谢您的帮助。我现在可以更进一步了。我可以注销,但如果数据库中存在“记住我”散列项,则注销时会出现错误致命错误:未捕获PDOException:SQLSTATE[HY000]:C:\xampp\htdocs\test_site.com\classes\db.php中的一般错误:81堆栈跟踪:#0 C:\xampp\htdocs\test_site.com\classes\db.php(81):PDOStatement->fetchAll(5)#1 C:\xampp\htdocs\test_site.com\classes\db.php(143):db->query('DELETE FROM use…',Array)#2 C:\xampp\htdocs\test_site.com\classes\db.php(156):db->action('DELETE',users_session',Array)#3$this->结果=$this->查询->获取全部(PDO::FETCH OBJ);现在是81号线。你知道发生了什么事吗?谢谢您的帮助。如果您将此添加到第81var_dump($this->_query->rowCount())行之前的行中,您会得到什么;出口谢谢你的提示。这是一个教程,但我会看看我是否可以修改这件事,以便我可以看到错误更好。谢谢