proxximo Posted March 17, 2007 Share Posted March 17, 2007 I am trying to make a script work for a game I am working on at the moment. The problem comes at the explode() and implode() functions. I am pulling an array out of a database with 5 items in it (ex. 1,0,0,0,0) Once the array is pulled I change one of the zeros to a new number and then implode the array back into the variable then back to the database. There is also a check to make sure that you have an open zero to use and change.Here is the code .... if ($userrow["potionpack"] == 0) { display("You do not have a potion pack. You must have that item in order to carry potions without spilling them.<br /><br />You may return to <a href=\"index.php?do=religiousdistrict\">town</a>, <a href=\"index.php?do=apothacary\">apothacary</a> to buy a potion pack, or use the navigation buttons on the left to start exploring.", "Buy Potions"); die(); } elseif ($userrow["potionpack"] == 1) { $potions1 = $userrow["potions"]; $potions = explode(",",$potions1); if ($potions[0] != 0) { $add1 = 1;} else { $add1 = 0;} if ($potions[1] != 0) { $add2 = 1;} else { $add2 = 0;} if ($potions[2] != 0) { $add3 = 1;} else { $add3 = 0;} if ($potions[3] != 0) { $add4 = 1;} else { $add4 = 0;} if ($potions[4] != 0) { $add5 = 1;} else { $add5 = 0;} $potioncount = $add1 + $add2 + $add3 + $add4 + $add5; if ($potioncount == 1) { $okaytobuy = 1; } elseif ($potioncount == 2) { $okaytobuy = 1; } elseif ($potioncount == 3) { $okaytobuy = 1; } elseif ($potioncount == 4) { $okaytobuy = 1; } elseif ($potioncount == 5) { $okaytobuy = 0; } if ($okaytobuy = 1) { $potions = explode(",",$potions1); $id = $itemsrow["id"]; if ($potions[0] == 0) { $potions[0] = "$id"; } else { if ($potions[1] == 0) { $potions[1] = "$id"; } else { if ($potions[2] = 0) { $potions[2] = "$id"; } else { if ($potions[3] = 0) { $potions[3] = "$id"; } else { if ($potions[4] = 0) { $potions[4] = "$id"; } else { $potions[4] = $potions[4]; } $potions[3] = $potions[3]; } $potions[2] = $potions[2]; } $potions[1] = $potions[1]; } $potions[0] = $potions[0]; } $potions = array($potions[0], $potions[1], $potions[2], $potions[3], $potions[4]); $potions = implode(",",$potions); } elseif ($okaytobuy = 0) { display("You do not have room in your potion pack. You must clean out some space to carry more potions or upgrade your pack.<br /><br />You may return to <a href=\"index.php?do=religiousdistrict\">town</a>, <a href=\"index.php?do=apothacary\">apothacary</a> to upgrade your potion pack, or use the navigation buttons on the left to start exploring.", "Buy Potions"); die(); } } The problem is that it is shooting the same end result every time 1,1,0,0,0 no matter what the beginning string is (1 is the id that I am testing)... can anyone see what I am not. I think I have just been staring at it too long now. Thanks ahead of time. Quote Link to comment Share on other sites More sharing options...
kenrbnsn Posted March 17, 2007 Share Posted March 17, 2007 This line: <?php if ($okaytobuy = 1) { ?> should have two equal signs, not one: <?php if ($okaytobuy == 1) { ?> That being said, I think you're doing way to much work for what you're trying to do. Here's a much shorter version that does what I think you were trying to do: <?php if ($userrow["potionpack"] == 0) { display("You do not have a potion pack. You must have that item in order to carry potions without spilling them.<br /><br />You may return to <a href=\"index.php?do=religiousdistrict\">town</a>, <a href=\"index.php?do=apothacary\">apothacary</a> to buy a potion pack, or use the navigation buttons on the left to start exploring.", "Buy Potions"); die(); } elseif ($userrow["potionpack"] == 1) { $potions1 = $userrow["potions"]; $potions = explode(",",$potions1); $add = array(); for($i=0;$i<count($potions1);$i++) $add[$i] = ($potions[$i] != 0)?1:0; $potioncount = array_sum($add); $okaytobuy = ($potioncount < 5)?true:false; if ($okaytobuy) { $id = $itemsrow["id"]; for ($i=0;$i<count($potions);$i++) if ($potions[$i] == 0) $potions[$i] = $id; $potions = implode(",",$potions); echo '<pre>' . print_r($potions,true) . '</pre>'; // debug line } else { display("You do not have room in your potion pack. You must clean out some space to carry more potions or upgrade your pack.<br /><br />You may return to <a href=\"index.php?do=religiousdistrict\">town</a>, <a href=\"index.php?do=apothacary\">apothacary</a> to upgrade your potion pack, or use the navigation buttons on the left to start exploring.", "Buy Potions"); die(); } } ?> Ken Quote Link to comment Share on other sites More sharing options...
proxximo Posted March 18, 2007 Author Share Posted March 18, 2007 First off Ken, thank you for taking the time to answer me. I tried the script and now instead of outputting 1,1,0,0,0 its outputting 1,1,1,1,1 every time. What I am trying to accomplish is turning just one of the 0's into a 1 each time I purchase. So if I start with 0,0,0,0,0, and I purchase it becomes 1,0,0,0,0 , then if I purchase again 1,1,0,0,0 etc, etc. Thanks again Quote Link to comment Share on other sites More sharing options...
kenrbnsn Posted March 18, 2007 Share Posted March 18, 2007 Since you only want to change the first zero to a one, you need to change the "buy" loop to something like this: <?php $bought = false; for ($i=0;$i<count($potions);$i++) if ($potions[$i] == 0 && !$bought) { $potions[$i] = $id; $bought = true; } ?> Ken Quote Link to comment Share on other sites More sharing options...
proxximo Posted March 18, 2007 Author Share Posted March 18, 2007 Ok this time I started with 0,0,0,0,0 did the first purchase and it made it 1,1,0,0,0 purchased again and it made it 1,1,1,1,0 so its doubling up... any ideas on why it would be doing that? Btw, Ken you are the man! Quote Link to comment Share on other sites More sharing options...
kenrbnsn Posted March 18, 2007 Share Posted March 18, 2007 It doesn't do that when I run my version of your code. Can you repost the code you're using? Ken Quote Link to comment Share on other sites More sharing options...
proxximo Posted March 18, 2007 Author Share Posted March 18, 2007 if ($userrow["potionpack"] == 0) { display("You do not have a potion pack. You must have that item in order to carry potions without spilling them.<br /><br />You may return to <a href=\"index.php?do=religiousdistrict\">town</a>, <a href=\"index.php?do=apothacary\">apothacary</a> to buy a potion pack, or use the navigation buttons on the left to start exploring.", "Buy Potions"); die(); } elseif ($userrow["potionpack"] == 1) { $potions1 = $userrow["potions"]; $potions = explode(",",$potions1); $add = array(); for($i=0;$i<count($potions1);$i++) $add[$i] = ($potions[$i] != 0)?1:0; $potioncount = array_sum($add); $okaytobuy = ($potioncount < 5)?true:false; if ($okaytobuy) { $id = $itemsrow["id"]; $bought = false; for ($i=0;$i<count($potions);$i++) if ($potions[$i] == 0 && !$bought) { $potions[$i] = $id; $bought = true; } $potions = implode(",",$potions); } } Quote Link to comment Share on other sites More sharing options...
proxximo Posted March 18, 2007 Author Share Posted March 18, 2007 Sorry I didnt cut the whole thing out .... here is the sript if ($userrow["potionpack"] == 0) { display("You do not have a potion pack. You must have that item in order to carry potions without spilling them.<br /><br />You may return to <a href=\"index.php?do=religiousdistrict\">town</a>, <a href=\"index.php?do=apothacary\">apothacary</a> to buy a potion pack, or use the navigation buttons on the left to start exploring.", "Buy Potions"); die(); } elseif ($userrow["potionpack"] == 1) { $potions1 = $userrow["potions"]; $potions = explode(",",$potions1); $add = array(); for($i=0;$i<count($potions);$i++) $add[$i] = ($potions[$i] != 0)?1:0; $potioncount = array_sum($add); $okaytobuy = ($potioncount < 5)?true:false; if ($okaytobuy) { $id = $itemsrow["id"]; $bought = false; for ($i=0;$i<count($potions);$i++) if ($potions[$i] == 0 && !$bought) { $potions[$i] = $id; $bought = true; } $potions = implode(",",$potions); } else { display("You do not have room in your potion pack. You must clean out some space to carry more potions or upgrade your pack.<br /><br />You may return to <a href=\"index.php?do=religiousdistrict\">town</a>, <a href=\"index.php?do=apothacary\">apothacary</a> to upgrade your potion pack, or use the navigation buttons on the left to start exploring.", "Buy Potions"); die(); } } Quote Link to comment Share on other sites More sharing options...
proxximo Posted March 18, 2007 Author Share Posted March 18, 2007 Bump ... Quote Link to comment Share on other sites More sharing options...
btherl Posted March 23, 2007 Share Posted March 23, 2007 Please try the following code (standalone), then try incorporating it (without all the debugging statements) <?php function display($s) { print $s; } $userrow['potionpack'] = 1; $userrow['potions'] = '0,0,0,0,0'; $itemsrow['id'] = 1; if ($userrow["potionpack"] == 0) { display("You do not have a potion pack. You must have that item in order to carry potions without spilling them.<br /><br />You may return to <a href=\"index.php?do=religiousdistrict\">town</a>, <a href=\"index.php?do=apothacary\">apothacary</a> to buy a potion pack, or use the navigation buttons on the left to start exploring.", "Buy Potions"); die(); } elseif ($userrow["potionpack"] == 1) { $potions1 = $userrow["potions"]; $potions = explode(",",$potions1); $add = array(); for($i=0;$i<count($potions);$i++) $add[$i] = ($potions[$i] != 0)?1:0; $potioncount = array_sum($add); print "potioncount: $potioncount\n"; $okaytobuy = ($potioncount < 5)?true:false; if ($okaytobuy) { $id = $itemsrow["id"]; $bought = false; for ($i=0;$i<count($potions);$i++) { print "Checking slot $i.. "; if ($potions[$i] == 0 && !$bought) { $potions[$i] = $id; $bought = true; print "Bingo! Allocating potion\n"; } else { print "nope\n"; } } $potions = implode(",",$potions); } else { display("You do not have room in your potion pack. You must clean out some space to carry more potions or upgrade your pack.<br /><br />You may return to <a href=\"index.php?do=religiousdistrict\">town</a>, <a href=\"index.php?do=apothacary\">apothacary</a> to upgrade your potion pack, or use the navigation buttons on the left to start exploring.", "Buy Potions"); die(); } } var_dump($userrow); var_dump($potions); ?> Quote Link to comment Share on other sites More sharing options...
proxximo Posted March 23, 2007 Author Share Posted March 23, 2007 Ok I ran the script and it is showing everything working right. It checks for the open slot, allocates it to the slot and shows that the implode should be 1,1,1,0 but when I look into the database it shows it being 1,1,1,1 ... so the script is doing what it should but somehow when it is placed into the database it is being doubled... any ideas there? Quote Link to comment Share on other sites More sharing options...
proxximo Posted March 23, 2007 Author Share Posted March 23, 2007 I have a feeling it is in the updating of the database so heres my code: Here is my update query $updatequery = doquery("UPDATE {{table}} SET $potions gold='$newgold' WHERE id='$userid' LIMIT 1", "users"); and the doquery function function doquery($query, $table) { // Something of a tiny little database abstraction layer. include('config.php'); global $numqueries; $sqlquery = mysql_query(str_replace("{{table}}", $dbsettings["prefix"] . "_" . $table, $query)) or die(mysql_error()); $numqueries++; return $sqlquery; } Quote Link to comment Share on other sites More sharing options...
btherl Posted March 23, 2007 Share Posted March 23, 2007 Try printing out the values of variables throughout your code, especially any code that may affect the potions data. You will find the bug. IF you don't find the bug, start printing out values of variables that you know could never ever ever ever ever ever EVER possibly be wrong I don't think it's your database query. Quote Link to comment Share on other sites More sharing options...
proxximo Posted March 23, 2007 Author Share Posted March 23, 2007 I dont understand how a variable can be correct one second, then as soon as a query is run the variable changes between the php script and the mysql table... I printed out every variable in the entire script and havent found any problems. all of the variables, INCLUDING the $potions variable are correct. Any other thoughts that I can try out? Quote Link to comment Share on other sites More sharing options...
btherl Posted March 23, 2007 Share Posted March 23, 2007 Did you print out the mysql statement itself? $sql = "UPDATE {{table}} SET $potions gold='$newgold' WHERE id='$userid' LIMIT 1"; print "About to run $sql<br>"; $updatequery = doquery($sql, "users"); Quote Link to comment Share on other sites More sharing options...
proxximo Posted March 23, 2007 Author Share Posted March 23, 2007 yup, here is the printout I get from the script potioncount: 0 Checking slot 0.. Bingo! Allocating potion Checking slot 1.. nope Checking slot 2.. nope Checking slot 3.. nope Checking slot 4.. nope Checking slot 5.. nope Checking slot 6.. nope Checking slot 7.. nope Checking slot 8.. nope Checking slot 9.. nope potions='1,0,0,0,0,0,0,0,0,0',About to run UPDATE {{table}} SET potions='1,0,0,0,0,0,0,0,0,0', gold='7260' WHERE id='1' LIMIT 1 However in the table the slot is 1,1,0,0,0,0,0,0,0,0 So it is mysql then? Quote Link to comment Share on other sites More sharing options...
btherl Posted March 23, 2007 Share Posted March 23, 2007 No, it's not mysql. Software as mature as mysql doesn't make mistakes, especially not ones like that. The only explanation is that your script is running ANOTHER query which is updating the database again. There are many ways that could happen.. it could be triggered by a browser or cache making two requests for whatever reason. It could be caused by accidentally including a file twice. Or it could be caused by having old code lying around. Another possibility is that some code you aren't expecting to run IS running, causing the second update. If possible, log all queries to a file. Then you can see what's really going on. Quote Link to comment Share on other sites More sharing options...
btherl Posted March 23, 2007 Share Posted March 23, 2007 Here's an idea to narrow down the cause of the bug. Immediately after the query which you know 100% does the correct update to the database, add exit(0), so the script terminates immediately. See if the database looks ok after that. Then try it without the exit() call. If the database has the correct value after the exit(), then you know that there is code running AFTER that point which is doing the second update. If the database still has the wrong value, then you know that the script must be being called a second time somehow. Quote Link to comment Share on other sites More sharing options...
proxximo Posted March 23, 2007 Author Share Posted March 23, 2007 Ok I ran the exit function and it worked great. So that means the script is beiing run twice? How do I find out how, why and where? Quote Link to comment Share on other sites More sharing options...
btherl Posted March 23, 2007 Share Posted March 23, 2007 Edit: No need to check if it's being run twice.. it isn't.. i'm not thinking today The other possibility is that some code later in your script does another query. You may have to print output for every single query you run to find which one it is. If doquery() is your own function, then just edit that and have it print out every single query passed into it. It's a lot of work, but you will find the problem And once you find it, you'll know how to stop it happening again. Quote Link to comment Share on other sites More sharing options...
proxximo Posted March 23, 2007 Author Share Posted March 23, 2007 Where will the code: file_put_contents("script_ran" . posix_getpid(), "Someone ran me!"); print "Someone ran me!" to? Will it print to a document somewhere? Quote Link to comment Share on other sites More sharing options...
btherl Posted March 23, 2007 Share Posted March 23, 2007 Don't worry about that.. I was off in la-la land. Just read the second part of what I wrote Because the exit() fixed things, that proves that the script runs another query later which updates the database again. So now you need to find where that happens. It also proves that the script isn't being run twice, so there's no need to check for that. Quote Link to comment Share on other sites More sharing options...
proxximo Posted March 23, 2007 Author Share Posted March 23, 2007 I dont do anyhting after that update except show the user they bought a potion ... $sql = "UPDATE {{table}} SET $potions gold='$newgold' WHERE id='$userid' LIMIT 1"; print "About to run $sql<br>"; $updatequery = doquery($sql, "users"); exit(0) $page .= "<center>Thank you for purchasing the ".$itemsrow["name"].".<br /><img src= $apothimage><br /><br />You may return to <a href=\"index.php?do=religiousdistrict\">town</a>, or the <a href=\"index.php?do=apothacary\">apothacary</a>, or use the navigation buttons on the left to start exploring.</center>"; $title = "Potion Purchased"; display($page, $title); } ?> so now Im really stumped.. Quote Link to comment Share on other sites More sharing options...
btherl Posted March 23, 2007 Share Posted March 23, 2007 That's the end of the entire script? Is that script included or required from any other script? Try altering doquery() so it prints out every single query its asked to run. As long as all your queries go through doquery(), it should be impossible for anything to slip past without being printed out. Quote Link to comment Share on other sites More sharing options...
proxximo Posted March 23, 2007 Author Share Posted March 23, 2007 I set up a new table devoted to nothing but users potions. I have it print out every query that goes through the doquery() function. And i made sure that the userpotions table isnt used anywhere else no matter what... I ran the script. When it prints out all of the querys it shows that the input should be 1,0,0,0 and it shows that query only being run one time. But when I go to the table it is input as 1,1,0,0. So the next question is can this script run twice and only show one run through the doquery() printout? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.