检查PDO中的会话ID是否为ISSET

时间:2012-12-31 02:30:05

标签: php pdo sessionid isset

我已切换到PDO准备好的语句,而且我的代码无法获取和使用会话ID。

当客户注册时,session_id被设置为等于user_id(自动递增),并且在用户返回时以相同的方式设置session_id。这在切换到PDO之前工作正常,但现在session_id在任何后续页面上都没有被识别(它正在查看' user_id'为空)

我是否需要切换到使用PDO会话处理程序,还是有办法继续使用我熟悉的方法?

mysql - 这是我用来设置会话ID的代码(这项工作正常):

// Statements defining $user_name, $password and $hashedPassword (as shown below), and mysql_real_escape_string
// Insert statement
if($result) { 
$qry="SELECT * FROM customer_info WHERE user_name='$user_name' AND password='".sha1($salt + $_POST['password'])."'";
$result=mysql_query($qry);
if($result) {
    if(mysql_num_rows($result) == 1) {
    session_regenerate_id();
    $member = mysql_fetch_assoc($result);
    $_SESSION['SESS_USER_ID'] = $member['user_id'];
    session_write_close();
    exit();
    } } }

PDO - 这是我尝试过的代码(会话ID未设置):

$user_name = $_POST['user_name'];
$password = $_POST['password'];  
$hashedPassword = sha1($salt . $password); 
$stmt = $conn->prepare('INSERT INTO customer_info (...) VALUES(...)');
$stmt->bindParam(':user_id', $user_id); 
...  
$insertResult = $stmt->execute();  
if ($insertResult) {
    $qry="SELECT * FROM customer_info WHERE user_name = $user_name AND password=$hashedPassword";
    if($qry) {
        $affected_rows = $stmt->rowCount();
        if ($affected_rows == 1)  {   
            session_regenerate_id();
            $member = $stmt->fetch();
            $_SESSION['SESS_USER_ID'] = $member['user_id'];   
        }  

允许我在后续网页上引用会话ID的其他代码

此代码位于每个后续页面的顶部:

<?php
  //Starts session and checks if the session variable SESS_USER_ID is present or not
  require_once('auth.php');  
  //Database connection and Open database
  require_once('config.php');  
  $user_id = $_SESSION['SESS_USER_ID']; 
?>

auth.php文件

<?php
session_start();
if(!isset($_SESSION['SESS_USER_ID']) || (trim($_SESSION['SESS_USER_ID']) == '')) {
    header("location: login_failed.html");
    exit();
}
?>

2 个答案:

答案 0 :(得分:2)

$stmt->fetch()的调用失败,因为此时$stmt仍然引用您无法从中获取行的SQL INSERT

所以你需要做的是执行一个SELECT语句来检索新输入的用户详细信息,并从中检索fetch()。假设您在customer_info表中有自动增量列,请使用PDO::lastInsertId()获取新行的ID,并在SELECT查询中使用它。

$user_name = $_POST['user_name'];
$password = $_POST['password'];  
$hashedPassword = sha1($salt . $password); 
$stmt = $conn->prepare('INSERT INTO customer_info (...) VALUES(...)');
$stmt->bindParam(':user_id', $user_id); 
...  
$insertResult = $stmt->execute();  
if ($insertResult && $stmt->rowCount() == 1) {
  // Ok, the INSERT was successful, so now SELECT the row back
  // Use lastInsertId() to get the new row's id
  // Assuming the id column is `user_id`...
  $stmt_user = $conn->prepare("SELECT * FROM customer_info WHERE user_id = :user_id");
  $stmt_user->bindValue(":user_id", $conn->lastInsertId());
  $stmt_user->execute();

  session_regenerate_id();
  // Fetch from the SELECT query
  $member = $stmt_user->fetch();
  $_SESSION['SESS_USER_ID'] = $member['user_id'];   
}

如果没有我假设为user_id的自动增量列,您可以通过绑定输入user_name和{{password$_POST['user_name']来执行查询1}}就像你原来的$hashedpassword代码一样。

答案 1 :(得分:2)

非常具体的问题

  

PDO - 这是我尝试过的代码(会话ID未被设置):

$user_name = $_POST['user_name'];
$password = $_POST['password'];  
$hashedPassword = sha1($salt . $password); 
$stmt = $conn->prepare('INSERT INTO customer_info (...) VALUES(...)');
$stmt->bindParam(':user_id', $user_id); 
...  
$insertResult = $stmt->execute();  
if ($insertResult) {
    $qry="SELECT * FROM customer_info WHERE user_name = $user_name AND password=$hashedPassword";
    if($qry) {
        $affected_rows = $stmt->rowCount();
        if ($affected_rows == 1)  {   
            session_regenerate_id();
            $member = $stmt->fetch();
            $_SESSION['SESS_USER_ID'] = $member['user_id'];   
        } 

现在仔细查看代码并在设置会话ID时回答问题? 这应该在以下时间完成:

1)$insertResult不是FALSE

哦,你的代码中有一个明显的错误,所以让我在这里停下来解释一下 -

$qry="SELECT * FROM customer_info WHERE user_name = $user_name AND password=$hashedPassword";

在这种情况下,这只是一个愚蠢的字符串。所以你的指导本身归结为:

if ($insertResult) { //Which always will be TRUE regarding result as the string isn't empty!!! 

if ($affected_rows == 1)  {   //if the number of affected rows == 1

然后执行INSERT会话ID


你究竟做错了什么

1)您不会跟踪错误,因此您无法捕捉到错误的确切性质 2)您不执行SQL语句并从中获取结果 3)如果是行数&#34;失败&#34;你没有跟踪这个,但确实忽略了这个

你应该做什么

1)执行语句:$qry="SELECT * FROM customer_info WHERE user_name = $user_name AND password=$hashedPassword";(也是SQL语句包含变量,好像你从旧的mysql_*函数中得到了这个),如

$stmt->prepare("SELECT * FROM customer_info WHERE user_name = :user_name AND password=:hashedPassword LIMIT 1;"); 
$stmt->execute(array(':user_name' => $username, ':hashedPassword' => $hashedPassword))); 
$result = $stmt->fetchAll(PDO::FETCH_ASSOC)

//now check $result if it found the row, like

if ( $result ){
   // found
} else {
   // not found, do track an error here
}

2)再次 - 保持错误跟踪。我可以建议你实现一个自定义错误处理程序,但为了一个例子,你可以使用一个数组。
它看起来像这样:

<?php

//at the bottom of the script
$errors = array();

...
...

if ( $result ){
  // do next stuff
  ...
} else {
  //add an error
  array_push('Incorrect data', $errors);
}

然后在某个地方,您可以简单地打印出错误,例如,

//We won't use a global keyword
function print_errors(array $errors){

   if ( !empty($errors) ){
        foreach($errors as $error){
           print '<p><li>' . $error . '</li></p>';
        }

   }
}


//Use like this:
print_errors($errors);

这样可以确保它确实存在的信心