我已切换到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();
}
?>
答案 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);
这样可以确保它确实存在的信心