Jump to content

implode, explode problems


proxximo

Recommended Posts

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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);
      }
}

Link to comment
Share on other sites

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(); 
    		}
}

Link to comment
Share on other sites

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);
?>

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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;

}

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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..

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.