我正在尝试为每个用户生成用户ID和关联的6位令牌。 对于活动用户,值必须是唯一的。为了确保唯一性,我以递归方式使用相应的函数。
在页面加载时生成值。除了(大多数情况下)当我快速重新加载页面时,我的脚本应该工作它会产生错误。除非我删除mysqli_close($dbLink)
语句。问题在于我关闭链接还是事实上函数是递归使用的,组合还是可能是完全不同的东西?
错误:
Warning: mysqli_prepare(): Couldn't fetch mysqli in C:\xampp\htdocs\project\functions.php on line 68
Warning: mysqli_stmt_bind_param() expects parameter 1 to be mysqli_stmt, null given in C:\xampp\htdocs\project\functions.php on line 69
Warning: mysqli_stmt_execute() expects parameter 1 to be mysqli_stmt, null given in C:\xampp\htdocs\project\functions.php on line 70
Warning: mysqli_close(): Couldn't fetch mysqli in C:\xampp\htdocs\project\functions.php on line 71
代码:
$user_id = generateUserId();
$token = generateToken($user_id);
function generateUserId(){
global $dbLink;
$user_id = openssl_random_pseudo_bytes(128);
$user_id = hash('md5', $user_id);
$query = "SELECT * FROM users WHERE user_id = '{$user_id}' AND user_active = 1";
$result_set = mysqli_query($dbLink, $query);
if (mysqli_num_rows($result_set) != 0) {
generateUserId();
}
return $user_id;
}
function generateToken($user_id){
global $dbLink;
//generate Token with different numbers
$numbers = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
$token = array();
while (count($token) < 6) {
$number = array_rand($numbers);
if (!in_array($number, $token)) {
array_push($token, $number);
}
}
$token = implode($token);
//check if token exists
$query = "SELECT * FROM users WHERE user_token = '{$token}' AND user_active = 1";
$result_set = mysqli_query($dbLink, $query);
if (mysqli_num_rows($result_set) != 0) {
generateToken($user_id);
}
//save token and user id in database
$query = "INSERT INTO users ";
$query.= " (user_id, user_token)";
$query.= " VALUES (?, ?)";
$stmt = mysqli_prepare($dbLink, $query);
mysqli_stmt_bind_param($stmt, 'ss', $user_id, $token);
mysqli_stmt_execute($stmt);
mysqli_close($dbLink);
return $token;
}
答案 0 :(得分:1)
问题在于关闭链接,你应该在调用函数后关闭它,而不是在里面。
顺便说一下,如果要在函数内部关闭它,请考虑在调用递归函数后不执行任何类型的sql语句或函数。
我会做的是提取此代码:
//save token and user id in database
$query = "INSERT INTO users ";
$query.= " (user_id, user_token)";
$query.= " VALUES (?, ?)";
$stmt = mysqli_prepare($dbLink, $query);
mysqli_stmt_bind_param($stmt, 'ss', $user_id, $token);
mysqli_stmt_execute($stmt);
在您的功能之外,这样您在关闭它之后就不会使用该链接。
另外......如果你的函数进行递归...让我说10次,插入该值10次是没有意义的,不是吗?
更简单的是,只需添加其他内容即可将其插入基础案例中:
function generateToken($user_id){
global $dbLink;
//generate Token with different numbers
$numbers = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
$token = array();
while (count($token) < 6) {
$number = array_rand($numbers);
if (!in_array($number, $token)) {
array_push($token, $number);
}
}
$token = implode($token);
//check if token exists
$query = "SELECT * FROM users WHERE user_token = '{$token}' AND user_active = 1";
$result_set = mysqli_query($dbLink, $query);
if (mysqli_num_rows($result_set) != 0) {
generateToken($user_id);
}else{
//save token and user id in database
$query = "INSERT INTO users ";
$query.= " (user_id, user_token)";
$query.= " VALUES (?, ?)";
$stmt = mysqli_prepare($dbLink, $query);
mysqli_stmt_bind_param($stmt, 'ss', $user_id, $token);
mysqli_stmt_execute($stmt);
mysqli_close($dbLink);
}
return $token;
}