我现在只是为了好玩而制作一些网站,但我被困在了某个点上。
我想执行一个小组任务,小组中的任何成员都可以启动它。团队的所有人都将获得相同的金币,经验并共享相同的冷却时间。我的数据库中有3个表(我只会显示重要信息)
Members:
username, level, experience, playergold
Levels:
level, required_experience
Groups:
leader, member_1, member_2, member_3, last_quest_started, quest_cooldown
Quests:
success_message, failed_message, chance, minimum_experience, maximum_experience, minimum_gold, maximum_gold, cooldown
我想以小组形式更新last_quest_started和quest_cooldown,我想更新每个成员的等级、经验、玩家金币
所以在得到组成员的每个用户名后,任务数据,计算经验和金币。我用它来更新:
if($select_members_info_stmt = $mysqli->prepare("SELECT members.username, members.level, members.experience, members.playergold, levels.required_experience FROM members INNER JOIN levels ON members.level = levels.level WHERE ((members.username = ?) OR (members.username = ?) OR (members.username = ?) OR(members.username = ?))"))
{
$select_members_info_stmt->bind_param('ssss', $leader, $member_1, $member_2, $member_3);
$select_members_info_stmt->execute();
$select_members_info_stmt->bind_result($selected_username, $level, $experience, $playergold, $required_experience);
while($select_members_info_stmt->fetch())
{
$now = time();
if($update_user_stats_stmt = $mysqli->prepare("UPDATE members SET level = ?, experience = ?, playergold = ? WHERE username = ?"))
{
$update_user_stats_stmt->bind_param('iiiiis', $new_level, $new_experience, $new_gold, $now, $cooldown, $selected_username);
$update_user_stats_stmt->execute();
if($update_user_stats_stmt->affected_rows == 0)
{
echo '<div>Because of a system error it is impossible to perform a task, we apologize for this inconvience. Try again later.</div>';
}
$update_user_stats_stmt->close();
}
else
{
printf("Update user stats error: %s<br />", $mysqli->error);
}
}
$select_members_info_stmt->close();
echo '<div>'.$success_message.'</div><br />';
}
else
{
printf("Select members info error: %s<br />", $mysqli_error);
}
但我不断得到:
更新用户统计信息错误:命令不同步;您现在无法运行此命令(4 次,这是我的组已满时的大小。
我只是找不到解决不同步错误的解决方案,因为我无法关闭 $select_members_info_stmt,因为那样它会停止获取。
请帮助我,因为我真的不知道该怎么办。
你不能像那样嵌套你的execute()
。
最好的解决方案是将该成员列表放入array()
一次,关闭连接,然后迭代该数组并更新每条记录。
它应该看起来像这样:
$select_members_info_stmt->bind_param('ssss', $leader, $member_1, $member_2, $member_3);
$select_members_info_stmt->execute();
$select_members_info_stmt->bind_result($selected_username, $level, $experience, $playergold, $required_experience);
$members = array();
while($select_members_info_stmt->fetch())
{
// tossing into the array
$members[] = array(
'selected_username' =>$selected_username,
'level' => $level,
'experience' => $experience,
'playergold' => $playergold,
'required_experience' => $required_experience
);
}
$select_members_info_stmt->close();
// Now iterate through the array and update the user stats
foreach ($members as $m) {
if($update_user_stats_stmt = $mysqli->prepare("UPDATE members SET level = ?, experience = ?, playergold = ? WHERE username = ?"))
{
// Note that you need to use $m['selected_username'] here.
$update_user_stats_stmt->bind_param('iiiiis', $new_level, $new_experience, $new_gold, $now, $cooldown, $m['selected_username']);
$update_user_stats_stmt->execute();
if($update_user_stats_stmt->affected_rows == 0)
{
echo '<div>Because of a system error it is impossible to perform a task, we apologize for this inconvience. Try again later.</div>';
}
$update_user_stats_stmt->close();
}
else
{
printf("Update user stats error: %s<br />", $mysqli->error);
}
}
您不能将主动运行的预准备语句嵌套在与 mysql 的同一连接上。 一旦对任何语句调用 execute()
,就不能在同一连接上运行另一个语句,直到该准备好的语句关闭。 一旦您开始执行第二个预准备语句,对第一个预准备语句的任何读取都将失败。
每个连接只能准备一个"实时"语句并在 mysql 服务器上运行
如果你真的需要嵌套你的准备好的语句,你可以建立2个单独的mysqli连接。