我编写了这段代码,该代码应该创建一个包含用户已兑换的所有凭单及其值的表格,但是它不起作用(什么都没有出现,也没有显示错误),所以我很困惑在这里做错了。有人可以帮忙吗?
$dsn = 'mysql:host=127.0.0.1;dbname=user_db;charset=utf8';
$conn = new PDO($dsn, $username1, $password);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stm_voucher = $conn->prepare("SELECT id FROM users WHERE username = :username");
$stm_voucher->bindParam(":username", $username, PDO::PARAM_INT);
$stm_voucher->execute();
while ($row = $stm_voucher->fetch(PDO::FETCH_ASSOC)) {
$id = $row["id"];
$stm_voucher2 = $conn->prepare("SELECT * FROM vouchers WHERE used_by = :id");
$stm_voucher2->bindParam(":id", $id, PDO::PARAM_INT);
$stm_voucher2->execute();
$rank = 1;
while ($row2 = $stm_voucher2->fetch(PDO::FETCH_ASSOC)) {
echo "<tr>
<td>{$rank}</td>
<td>{$row2['voucher']}</td>
<td>{$row2['value']}</td>
<td>{$row2['used_on']}</td>
</tr>";
$rank++;
}
}
答案 0 :(得分:1)
类似这样,请使用Join而不是2个查询,因为这将节省大量性能并简化您的代码。通常,您在DB层中可以做的越多,则在应用程序中编写代码的次数就越少。在这种情况下,请输入-6行代码。
这应该替换您在问题中拥有的所有代码:
$dsn = 'mysql:host=127.0.0.1;dbname=user_db;charset=utf8';
$conn = new PDO($dsn, $username1, $password);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare("SELECT v.* FROM users AS u JOIN vouchers AS v ON u.id = v.used_by WHERE u.username = :username");
$stmt->execute([":username" => $username]);
$rank = 1;
while ($row2 = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "<tr>
<td>{$rank}</td>
<td>{$row2['voucher']}</td>
<td>{$row2['value']}</td>
<td>{$row2['used_on']}</td>
</tr>";
$rank++;
}
不要忘记<table></table>
标签。我在其中看不到它们,也没有在$username
中定义它们。但是我必须假设它们是正确的。
我通过这种方式了解了两个表之间的关系
如果vouchers.used_by = :id
和->bindParam(":id", $id,..)
和$id = $row["users.id"];
然后vouchers.used_by = users.id
。基本上是等价原理。
如果不知道,可以使用JOIN的方式访问多个表,使左表中的一个(或多个)字段与右表中的一个字段相关(它们是相同的数据)。最重要的2个是INNER JOIN
又名JOIN
和LEFT JOIN
-JOIN要求两个表中都有匹配的行,LEFT JOIN则只需要LEFT中的匹配行手表。
因此,通过左联接,您可以找到仅存在于左表中的行,而JOIN要求两个表中都存在相关行。根据您仅使用users
表中的ID来从vouchers
表中提取相关记录的情况,您似乎只需要常规的JOIN
就可以消除查找的需要users.id
,因为JOIN会这样做。而且,您实际上只需要vouchers
表中的数据。
希望如此。
在评论Nigel Ren
中,我认为这是问题的根源:
用户名确实是一个整数-(“:username”,$ username,PDO :: PARAM_INT)
使用PDO,您只需将输入内容放入数组中即可执行。基本上将所有输入视为字符串类型。因此,假设$username
已正确定义,这也应该回避该问题。人们会希望用户名类似于myaccount
而不是1
,而是字符串而不是int。
希望有帮助!