tags:

views:

262

answers:

2

I'm having a really strange problem with this code I'm working on at the moment. It's a map editor for a game that sends the variables for each tile to another PHP file to update the mySQL database.

So far the map editor code displays the map and loads everything fine. The map update (mupdate) PHP file correctly updates the database, if given the variables directly in the code.

However, when I send the data as a POST variable between the files, the mupdate file receives them perfectly for the first 18 times or so, then fails to read any more.

Can anyone shed a little light on why this is happening?

(Apologies in advance for my scruffy coding and for the ridiculous load time of the map editor it is loading an entire map, I may change that to 10x10 sections at some point, but the POST var problem still applies.)

The map editor:

http://www.locktopia.netne.net/mapedit.php
<?php
//Database Connection
include('DBconnect.php');


//Map Defaults
$world="slums";
$mapInfo=mysql_fetch_assoc(
  mysql_query("SELECT * FROM `mapindex` WHERE `NAME` = '".$world."'")
);
$tileSet= $mapInfo['TILESET'];

//Loads Current Location
// Splits the Database Location into the co-ordinates.
$startX=$startY = 1;
list($maxX, $maxY) = split('[,]', $mapInfo['SIZE']);

//Listing tiles in directory
$tileDir = "images/tileSets/".$tileSet."/";

$tilecount = count(glob("" . $tileDir . "*.png"));
$objDir = "images/tileSets/objects/";

$Objcount = count(glob("" . $objDir . "*.png"))-1;

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  <title>Map Editor</title>
</head>
<body>

//MAP EDITOR V2
<form action="mupdate.php" method="post">
<?php
  //Map and Co-Ord values
  echo('<input name="world" type="hidden" id="world" value="'.$mapInfo['NAME'].'" />');
  echo('<input name="size" type="hidden" id="size" value="'.$mapInfo['SIZE'].'" />');
?>
<table width="100%" border="1" cellpadding="0" cellspacing="0">
<?php
  echo($mapInfo['NAME']);
  echo($mapInfo['SIZE']);

  while($startY<=$maxY){
    echo("<tr>"); //BEGIN ROW
    while($startX<=$maxX){
      echo("<td>");//BEGIN CELL
      ///////////////////////CELL CONTENT///////////////////////

      //Tile Menu
      echo('Tile:<br /><select name="'.$startX.','.$startY.'-tile" id="'.$startX.','.$startY.'-tile" size="1" style="overflow:scroll;width:40px;height:20px;">');
      $possibleTile=1;
      while($possibleTile<=$tilecount){
        echo('<option value="'.$possibleTile.'" style="width:40px; height:40px; background-image: url('.$tileDir.$possibleTile.'.png);">'.$possibleTile.'</option>');
        $possibleTile++;
      }
      echo('</select><br />');

      echo('Obj LVL1:<br /><select name="'.$startX.','.$startY.'-ob1" id="'.$startX.','.$startY.'-ob1" size="1" style="overflow:scroll;width:40px;height:20px;">');
      $possibleObject=0;
      while($possibleObject<=$Objcount){
        echo('<option value="'.$possibleObject.'" style="width:40px; height:40px; background-image: url('.$objDir.$possibleObject.'.png);">'.$possibleObject.'</option>');
        $possibleObject++;
      }
      echo('</select><br />');

      echo('Obj LVL2:<br /><select name="'.$startX.','.$startY.'-ob2" id="'.$startX.','.$startY.'-ob2" size="1" style="overflow:scroll;width:40px; height:20px;">');
      $possibleObject=0;
      while($possibleObject<=$Objcount){
        echo('<option value="'.$possibleObject.'" style="width:40px; height:40px; background-image: url('.$objDir.$possibleObject.'.png);">'.$possibleObject.'</option>');
        $possibleObject++;
      }
      echo('</select>');

      echo('Buildable:<br /><select name="'.$startX.','.$startY.'-build" id="'.$startX.','.$startY.'-build" size="1" style="overflow:scroll;width:40px; height:20px;">');
      $possibleOption=0;
      while($possibleOption<=1){
        echo('<option value="'.$possibleOption.'">'.$possibleOption.'</option>');
        $possibleOption++;
      }
      echo('</select>');

      echo('Type:<br /><select name="'.$startX.','.$startY.'-type" id="'.$startX.','.$startY.'-type" size="1" style="overflow:scroll;width:40px; height:20px;">');
      echo('<option value="passable">Walkable</option>');
      echo('<option value="impassable">Blocked</option>');
      echo('<option value="teleport">Teleport</option>');
      echo('</select>');

      //////////////////////////////////////////////////////////
      echo("</td>");//END CELL
      $startX++;
    }
    echo("</tr>");//END ROW
    $startY++;
    $startX=1;
  }
?>
</table>
<input type="submit" name="submit" />
</form>
</body>
</html>

Map Updater: [Clicking Submit on the above page will take you to it)

 <?php
//Database Connection
include('common/connectDB.php');

//Printing the Data in the POST array
print_r($_POST);

// A Spacer for convenience's sake
echo('<br /><hr> <br />');

//Setting the Name of the map to update
$mapName=$_POST['world'];

//Getting the Max X/Y dimensions of the map (in tiles)
list($mapX, $mapY) = split('[,]', $_POST['size']);

//Setting the start points for the loops
$currX=1;
$currY=1;

//Row (Y-Axis) Update Loop
while($currY<=$mapY){

    //Column (X-Axis) Update Loop
    while($currX<=$mapX){

     //Checking for missing data on cell Type (Walkable/Blocking/Teleport)
     if(empty($_POST[$currX.','.$currY.'-type'])) {
          die("Failed on 'type': currX={$currX} - currY={$currY} - POST DATA: {$_POST[$currX.','.$currY.'-type']}");
     }

     //Checking for missing data on cell Tile (The base graphic, represented by a number which matches an image file)
     if(empty($_POST[$currX.','.$currY.'-tile'])) {
          die("Failed on 'tile': currX={$currX} - currY={$currY} - POST DATA: {$_POST[$currX.','.$currY.'-tile']}");
     }

     //mysql_query
     echo("UPDATE `maps` SET `TYPE`='".$_POST[$currX.','.$currY.'-type']."', `TILE` = '".$_POST[$currX.','.$currY.'-tile']."', `BUILD` = '".$_POST[$currX.','.$currY.'-build']."', `OBJECTS` = '".$_POST[$currX.','.$currY.'-ob1'].",".$_POST[$currX.','.$currY.'-ob2']."' WHERE  CONVERT( `maps`.`MAP` USING utf8 ) = '".$mapName."' AND CONVERT( `maps`.`XY` USING utf8 ) = '".$currX.",".$currY."'");

     //A spacer for Clarity's sake
     echo('<br />');

     //Updating the Column (X-Axis) Value
     $currX++;
    }
    echo("Row ".$currY." of ".$mapY." completed.<br>Sleeping 1 Second."); 

    //Resetting Column (X-Axis) to 1
    $currX=1;

    //Updating the Column (Y-Axis) Value
    $currY++;

    //A spacer for Clarity's sake
    echo('<br />');

    //Sleep for 1 Second. Stops the DB being overloaded with requests (as discovered with my map generator)
    //sleep(1); //uncommented in working version
}

//Closing the DB connection
mysql_close();
?>

Just to Clarify: The Output of the Code fails to include the Values for Tile, Type and Build after the 19th entry:

Compare:

No. 19 -

UPDATE `maps` SET `TYPE`='passable', `TILE` = '1', `BUILD` = '0', `OBJECTS` = '0,0' WHERE CONVERT( `maps`.`MAP` USING utf8 ) = 'slums' AND CONVERT( `maps`.`XY` USING utf8 ) = '19,1'

No. 20 -

UPDATE `maps` SET `TYPE`='', `TILE` = '1', `BUILD` = '', `OBJECTS` = '0,0' WHERE CONVERT( `maps`.`MAP` USING utf8 ) = 'slums' AND CONVERT( `maps`.`XY` USING utf8 ) = '20,1'

No. 21 -

UPDATE `maps` SET `TYPE`='', `TILE` = '', `BUILD` = '', `OBJECTS` = ',' WHERE CONVERT( `maps`.`MAP` USING utf8 ) = 'slums' AND CONVERT( `maps`.`XY` USING utf8 ) = '21,1'

Appendix: Thanks Phil for pointing out the mysql_close() mistake, I've added the code you suggested and also added a check for another var (I can't use it to check for build though as it uses a single int as true or false). Interestingly enough, one time the printr($_POST); gave me the complete amount of data, but the rest of the code failed at number 20, now it only displays it up to number 20. I'm wondering if it would help if I made the post values in arrays (i.e. $_POST[20,1][type])

A: 

The first thing I would do to try to pin point the problem is to call

print_r($_POST) before $mapName=$_POST['world'];

Then, I would add the following in your 2nd loop:

if(empty($_POST[$currX.','.$currY.'-type'])) 
     die("Failed: currX={$currX} - currY={$currY} - POST DATA: {$_POST[$currX.','.$currY.'-type']}");

Also, mysql_close takes parentheses () => mysql_close();

I hope that helps

philhq
+1  A: 

Things to potentially look at:

  1. Script time outs

  2. POST size. There are limits, see the post_max_size in the php.ini

Chris Lively
1. Possibly, but before I added the die() code recommended by Phil, it continued to output the mysql query untill it reached the end, also, when testing the mupdate.php file with Vars I gave it directly in the code, it updated the Database entries without a hitch (sleeping 1 second after each row) so I'm not sure it's that.2. This seems quite likely to me, were it not for that time that the $_POST printout gave me all the data intact, but the code below didn't. Unfortunately I don't have access to the php.ini file, the server is a free hosting account with 000webhost, so access is limited.
I *think* the php default is 2MB, but I'm not sure how much data your actually transfering. You might ask the provider what the value is.
Chris Lively
I'd guess that they'd be providing the default value, especially since the php config they offer includes pretty much everything from Zend to GD-lib.The 2MB makes sense though, it also explains why my Map Generator failed before I added the sleep(1) (original stress test was of a 200x200 tile map, total entries 40,000, Roughly 5 fields per entry, total size of SQL query as a txt doc: Just over 2MB)
If you can break it up into smaller chunks, try that.
Chris Lively