上下文:我正在查询数据库,以返回指定数量的怪物,以便在简单的基于网络的RPG中进行战斗。
问题:我有一个简单的MYSQL查询,其中包含一个WHERE子句来确定怪物的“级别”。在上一个函数中,我正在构建一个数组,其中包含应返回的相应怪物的级别;类似的东西:
$levels = Array( [0] => 3 [1] => 1 [2] => 1 )
所以在上面的数组中,Value对应于级别。所以我想回归3个怪物 - 等级3,等级1和等级1。
足够简单。现在我想使用以下内容查询MYSQL,并且可能使用循环来执行查询3次以获得我的3个怪物;类似的东西:
$query = "SELECT *, CardHP as EncounterCardHP, CardAP as EncounterCardAP";
$query .= " FROM Cards";
$query .= " WHERE CardTypeId = 1 AND CardRarity = {$level}";
$query .= " ORDER BY RAND() LIMIT 1";
因此在上面的查询中,变量{$ level}是前一个数组中的Monster Level。循环格式化是我努力的地方。我正在尝试这样的事情:
while ($i = $levels) {
$query = "SELECT *, CardHP as EncounterCardHP, CardAP as EncounterCardAP";
$query .= " FROM Cards";
$query .= " WHERE CardTypeId = 1 AND CardRarity = {$i}";
$query .= " ORDER BY RAND() LIMIT 1";
$result_set = mysql_query($query, $connection);
confirm_query($result_set);
return $result_set;
}
我认为这很接近,但我没有看到我如何才能最终从MYSQL中获得一个怪物阵列。看来在上面,我正在构建3个独立的数组?我是否需要使用array_merge(),还是有更简单更优雅的方法来执行此操作?如果我得到所有相同级别的怪物,我可以简单地运行查询1次和LIMIT 3,但我需要怪物对应于前面的数组显示的内容。
有意义吗?总是感谢帮助。
答案 0 :(得分:2)
我猜你需要WHERE IN
。
$query = "SELECT *, CardHP as EncounterCardHP, CardAP as EncounterCardAP";
$query .= " FROM Cards";
$query .= " WHERE CardTypeId = 1 AND CardRarity IN (".implode(',', $levels).")";
$query .= " ORDER BY RAND() LIMIT 1";
答案 1 :(得分:2)
我不完全明白你要做什么,但这应该循环并让你的阵列:
foreach ($levels as $key => $value) {
$query = "SELECT *, CardHP as EncounterCardHP, CardAP as EncounterCardAP FROM Cards WHERE WHERE CardTypeId = 1 AND CardRarity = {$value} ORDER BY RAND() LIMIT 1";
$results = mysqli_query($connection, $query);
while($row = $result->fetch_array(MYSQLI_BOTH)) {
$monsters[$key]['HP'] = $row['CardHP'];
//Add as needed
}
}
它创建一个多维数组,其中第一个键与级别中的键相同,后续键是SQL查询的结果。
$monsters = array(
[0] => array(
['HP'] => 10
['AP'] => 5
)
[1] => array(
['HP'] => 5
['AP'] => 7
)
)
另外,mysqli可能更适合您使用,因为它支持程序样式以及面向对象,并且大多数功能完全相同,尽管使用了mysqli前缀。
答案 2 :(得分:0)
实际上比我想象的容易得多;也许我过度解释了这个问题。这就是我所做的。
1)一旦我返回我的数组$ level,如下所示:
$levels = Array( [0] => 3 [1] => 1 [2] => 2 )
2)我创建了一个名为$ result_set的空数组 2)然后使用foreach循环遍历$ levels数组,并使用$ levels数组中的第一个$ level运行查询。但是,我不是仅返回带有返回的第一行的$ result_set,而是将第一行插入到我在步骤2中创建的空数组中。在每次循环之后,我将新行从MYSQL插入到现在填充的$ result_set数组中。
最后这是它的样子:
$result_set = array();
foreach ($levels as $level) {
$query = "SELECT *, CardHP as EncounterCardHP, CardAP as EncounterCardAP";
$query .= " FROM Cards";
$query .= " WHERE CardTypeId = 1 AND CardRarity = {$level}";
$query .= " ORDER BY RAND() LIMIT 1";
$result = mysqli_query($query, $connection);
$result_set[] = mysqli_fetch_array($result);
confirm_query($result_set);
}
return $result_set;
我的$ result_set现在有3个怪物,3级,1级和2级,都是从数据库中随机选择的。
感谢您的帮助。
答案 3 :(得分:0)
这是一种基于每个$levels
元素生成随机绘制的怪兽的单个结果集的安全方法。
这只是一次访问数据库的好习惯。同时,我应该提到RAND()
并不是以其性能而闻名。如果您在同一结果集中对随机性,加权随机化或没有重复的怪物有要求,则可能需要考虑其他策略。
$param_types = '';
foreach ($levels as $level) {
$selects[] = "(SELECT CardName, CardHP, CardAP FROM Cards WHERE CardTypeId = 1 AND CardRarity = ? ORDER BY RAND() LIMIT 1)";
$param_types .= 'i';
}
$conn = new mysqli('localhost', 'root', '', 'dbname');
$stmt = $conn->prepare(implode(' UNION ALL ', $selects));
$stmt->bind_param($param_types, ...$levels);
$stmt->execute();
$result = $stmt->get_result();
return $result->fetch_all(MYSQLI_ASSOC);
上面的代码段与此answer of mine密切相关。
我已经准备了一个工作演示,其中包含一些虚构数据,以证明我的解决方案有效。
模式(MySQL v5.7):
CREATE TABLE `Cards` (
id INT(11),
CardName VARCHAR(255),
CardTypeId INT(11),
CardRarity INT(11),
CardHP INT(11),
CardAP INT(11)
);
INSERT INTO `Cards` VALUES
(1, 'Dracula', 2, 1, 500, 75),
(2, 'Gargamel', 1, 1, 200, 20),
(3, 'Rumplestiltskin', 1, 2, 175, 45),
(4, 'Megatron', 3, 3, 1000, 300),
(5, 'Smeagol', 1, 1, 225, 60),
(6, 'Cruella Deville', 4, 1, 95, 35),
(7, 'Thanos', 1, 3, 2575, 960),
(8, 'Stay Puft', 1, 3, 800, 255),
(9, 'Keyser Soze', 1, 3, 750, 300);
查询:
(SELECT CardName, CardHP, CardAP FROM Cards WHERE CardTypeId = 1 AND CardRarity = 3 ORDER BY RAND() LIMIT 1)
UNION ALL
(SELECT CardName, CardHP, CardAP FROM Cards WHERE CardTypeId = 1 AND CardRarity = 1 ORDER BY RAND() LIMIT 1)
UNION ALL
(SELECT CardName, CardHP, CardAP FROM Cards WHERE CardTypeId = 1 AND CardRarity = 1 ORDER BY RAND() LIMIT 1);
可能的结果集:
| CardName | CardHP | CardAP |
| --------- | ------ | ------ |
| Stay Puft | 800 | 255 |
| Smeagol | 225 | 60 |
| Gargamel | 200 | 20 |