I used an example on PHP’s site to use in my script, but not sure what I’m doing wrong.
Here is the code
if (!empty($_POST['turnsUsed'])) {
$query = "SELECT minerals.id, minerals.mineral FROM minerals";
$input= getContent($query); //getContent is a function Im using to get the results from the database.
$turnsUsed = $_POST['turnsUsed'];
$x = 1;
while($x <= $turnsUsed) {
// $input = array("gold", "silver", "platinum", "bronze", "copper");
$rand_keys = array_rand($input, 2);
echo "<div><h2>Drilling attempt #$x you found</h2> ";
echo rand(0,5)." pieces of ".$input[$rand_keys[0]]."</div>";
$x++;
}
$newTurns = $turns - $turnsUsed;
$sql=$oDB->Prepare("UPDATE turns SET turns=:turns WHERE id=:userid");
$sql->execute(array(':turns' => $newTurns, ':userid' => $uid));
}
The var dump of my array contains this (it looks a bit messed up so I believe the reason for my problem is here somewhere.)
Im thinking of just doing another while loop and fill out a new array with only the mineral names instead of using the array above. Is that a better way to do it ?
What happens if turnsused is not a number? Since you haven’t validated it that field can contain anything at all. What information about your served will be exposed when a non number crashes your code?
The array contains both numeric and associative keys.
My guess would be that the database has “id” and “mineral” fields, - but - the script will choke when it looks for “0” and “1” fields.
I wouldn’t bother with a while loop, I’d try to get the array to be associative keys only when it’s created.
I want the script to pick random minerals and a random amount for each mineral picked, then put it into the database. Its a mining script in a browser game I’m making lol. So they choose how many turns they wanna spend mining and each turn gives a random amount of a random material.
public array PDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument [, array $ctor_args = array() ]]] )
fetch_style
Controls the contents of the returned array as documented in PDOStatement::fetch(). Defaults to value of PDO::ATTR_DEFAULT_FETCH_MODE (which defaults to PDO::FETCH_BOTH)
I updated my code with using rand() instead like this and it seems to work, but if I add more minerals in the database I will have to go back here and edit the numbers, so I will make a count. Is this a good or bad idea ?
Thanks everyone, I got it working as expected. (I think) This is the full code Im using. Anything wrong with the code or something I should do different ? One of the problems I see is alot of DB queries and by adding numbers with a positive + in front will give them more turns when they are out of turns lol.
<?php
include "template/header.php";
$dbQuery = "SELECT * FROM turns WHERE userID = ".$uid;
$data = getContent($dbQuery);
foreach($data as $row) {
$turns = $row['turns'];
}
if (!empty($_POST['turnsUsed']) && $_POST['turnsUsed'] <= $turns) {
if ($_POST['turnsUsed'] > 25) {
$turnsUsed = 25;
}
else {
$turnsUsed = $_POST['turnsUsed'];
}
$x = 1;
while($x <= $turnsUsed) {
$dbQuery = "SELECT minerals.id, minerals.mineral FROM minerals";
$input = getContent($dbQuery);
$rand_keys = rand(0,9);
$amount = rand(0,5);
echo "<p>Drilling attempt #$x you found: ";
echo $amount." pieces of ".$input[$rand_keys][mineral]."</p>";
$x++;
$sql=$oDB->Prepare("UPDATE bank SET amount=amount+:amount WHERE minerID=:minerID AND userID=:userID");
$sql->execute(array(':minerID' => $input[$rand_keys][id],':amount' => $amount, ':userID' => $uid));
}
$newTurns = $turns - $turnsUsed;
$sql=$oDB->Prepare("UPDATE turns SET turns=:turns WHERE id=:userid");
$sql->execute(array(':turns' => $newTurns, ':userid' => $uid));
}
elseif ($_POST['turnsUsed'] > $turns) {
echo "You don't have that many turns to spend.";
}
elseif ($_SERVER['REQUEST_METHOD'] == 'POST') {
echo '<h2>You need to add a # of turns in the box below to mine for minerals.</h2>';
}
echo '<p>You have a total of '.$turns.' turns! (max 25 turns each time)</p>';
echo 'How many turns do you want to use for mining ? ';
echo '<form method="POST" action="mining.php">
<span class="style-1"><input type="text" name="turnsUsed"></span>
<span class="style-1"><input type="submit" value="Start drilling!!"></span>
</form>';
?>
With the first query you’re only using the “turns” field so only select the “turns” field. If you’re using PDO it has a fetchall method which can grab the result set in one hit - eliminating a loop. How many rows do you expect to be returned by the first query.
Is the value for $uid coming from session data? If it’s not, make sure it’s validated, if it’s numeric an easy way is to typecast it as an integer, any non-numeric value will be changed to 0.
With the second query, do you expect to act on the same mineral twice? If not consider moving the second query outside of the while loop.
For the third query you might want to consider building a bulk update query then the execution of that query could be moved outside of the loop, meaning only hitting the DB once there.
You should consider wrapping all the from (including) the first query down to the end of the main loop (including) the third query in a transaction
Thanks for your help. I will do what you say. The first query I just need the amount of turns. the $uid is from the session data. I only have 10 different minerals for now in the database, I just wanted the user receive some random amounts of some random minerals so for now I dont mind if the same one appear twice, but I may change that later.