破译函数"Remember Me"堆栈跟踪错误



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

我的错误发生时,我点击注销按钮;

Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error inC:xampphtdocstestrongite.comclassesdb.php:51堆栈跟踪:#0C: xampp 根类 testrongite.com db.php (51):PDOStatement→fetchAll (5) # 1C: xampp 根类 testrongite.com db.php (77): DB→查询("删除从使用…', Array) #2C: xampp 根类 testrongite.com db.php (90): DB→行动("删除",'users_session', Array) #3C: xampp 根类 testrongite.com user.php (243):delete('users_session', Array) #4C:xampphtdocstestrongite.comlogout.php(5): User->logout() #5 {main}C:xampphtdocstestrongite.comclassesdb.php第51行

如果我注释掉这些代码;

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

我没有得到致命错误。但是,我无法删除数据库中为保留'remember me' 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

尝试检查在调用数据库查询方法中的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;
}

your ">致命错误">未捕获的PDOException";. 这是什么,你的PDO代码应该包装在一个try{...}catch()块。为了方便起见,您可以简单地将每个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));
}

通常最简单的方法是像上面的例子那样简单地放置一个捕获所有全局异常(Exception),而不是放置大量不同的特定异常,但是一旦您对这个概念更加熟悉,代码中就会有这个选项。

当一个动作(比如你的删除)失败时,这将给你基本的反馈,以及它失败的原因(在这种情况下,写入你的PHP错误日志)。

这不会解决核心问题(你在delete查询之后执行fetchAll),但会阻止生成致命错误并破坏你的应用程序。然后,您可以更适当地处理此问题,例如向用户输出消息。

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

最新更新