Jump to content

If statement making me mad!


reportingsjr

Recommended Posts

What would it do if you use alot of memory?

<?if (!function_exists("str_split")){  function str_split($str, $nr=1) {  	 return array_slice(split("-l-", chunk_split($str, $nr, '-l-')), 0, -1);  }}include "";$maptext = file_get_contents("bitmaps/map1.map");$map = explode("\n", $maptext);foreach ($map as $i => $mapline){  $map[$i] = str_split($mapline);  memory_get_usage();}echo "test";$position = mysql_fetch_object($database->query("SELECT * FROM `map` WHERE name = '{$_GET['username']}'"));$up = $position->y - 2;$down = $position->y + 2;$left = $position->x + 2;$right = $position->x - 2;if($_GET['way'] == "up"){	//GO UP	if($map[$up][$position->x] == "."){		$database->query("UPDATE `map` SET y = y-2 WHERE name = '{$_GET['username']}'");	}}elseif($_GET['way'] == "down"){	//GO DOWN	if($map[$down][$position->x] == "."){		$database->query("UPDATE `map` SET y = y+2 WHERE name = '{$_GET['username']}'");	}}elseif($_GET['way'] == "left"){	//GO LEFT	if($map[$position->y][$left] == "."){		$database->query("UPDATE `map` SET x = x-2 WHERE name = '{$_GET['username']}'");	}}else{	//GO RIGHT		if($map[$position->y][$right] == "."){			$database->query("UPDATE `map` SET x = x+2 WHERE name = '{$_GET['username']}'");		}}?>

So what would this class do exactly? How would you compile the map?looks like the very last array it does ends up giving it 8352616 bytes of memory 0.o . So help would be nice :). Your the best steve!

Link to comment
Share on other sites

If it used a lot of memory, it would either 1) slow the server down, 2) crash the server, or (hopefully) 3) just give an error.To compile the map, the class would write out a PHP script that statically defines the array, and then just include that file instead of parsing the map and building the array dynamically. I'm assuming that's where the memory is getting taken up, rather then just having the array in memory. Hopefully, compiling the map will not give an error.So, to make a map class, I guess we start with a class definition. The class would need methods to load the map, compile the map, and check coordinates. I'll start writing something and see what I come up with.

Link to comment
Share on other sites

Can you go into gabbly chat or something? I am still confused! Yes, the memory is all getting used up in the array. How would you statically define it? What do you mean by that? So, gabbly chat please?

Link to comment
Share on other sites

Sorry, I didn't see that in time and I'm already finished. Here is the class definition, save this as class.GameMap.php:

<?phpclass GameMap{  # declare properties  var $map_ar;  var $map_name;  var $is_compiled;  var $is_loaded;  # constructor  function GameMap($name = "")  {	# create an empty array	$this->map_ar = array();		$this->map_name = "";		# initialize boolean properties to false	$this->is_compiled = false;	$this->is_loaded = false;	# if a name was given, call the SetMap method	if ($name != "")	  $this->SetMap($name);  }  # SetMap will check for the file, set the map_name property,   # and call the CheckCompiled and LoadMap functions  function SetMap($name)  {	if (file_exists($name))	  $this->map_name = $name;	else	  die ("Class " . __CLASS__ . " error: the map file does not exist.");	$this->CheckCompiled();	$this->LoadMap();  }  # CheckCompiled determines if there is a file with the same name  # as the map file with a .compiled extension on the end  function CheckCompiled()  {	$this->is_compiled = false;	if ($this->map_name != "" && file_exists($this->map_name . ".compiled"))	{	  $this->is_compiled = true;	}	return $this->is_compiled;  }  # CompileMap will write a PHP file containing a static array declaration  function CompileMap()  {	if ($this->map_name == "")	  die ("Class " . __CLASS__ . " error: CompileMap has been called without setting a map file.");	# get the contents of the map file	$contents = file_get_contents($this->map_name);		# split up into lines	$lines = explode("\n", $contents);	# open the compiled map file for writing and truncate it	if (!$fh = fopen($this->map_name . ".compiled", "wb+"))	{	  die ("Class " . __CLASS__ . " error: Could not open map file for writing (" . $this->map_name . ".compiled).");	}	# write the opening PHP and declaration	$str = "<" . "?php\n" . "\$_a = array();\n";	fwrite($fh, $str);	# iterate through the lines	for ($i = 0; $i < count($lines); $i++)	{	  # create a new temp array for the line	  $str = "\$_b = array();";	  fwrite($fh, $str);	  # iterate through the characters on the line	  for ($j = 0; $j < strlen($lines[$i]); $j++)	  {		# add the current character to the temp line array		$str = "\$_b[] = \"{$lines[$i][$j]}\";";		fwrite($fh, $str);	  }	  # add the temp line array to the base array	  $str = "\$_a[] = \$_b;";	  fwrite($fh, $str);	}	# return the base array and end the PHP	$str = "\nreturn \$_a;\n?" . ">";	fwrite($fh, $str);	fclose($fh);  }  # LoadMap checks if the map has been compiled and sets the map_ar property  # to the array included in the compiled file  function LoadMap()  {	if ($this->map_name == "")	  die ("Class " . __CLASS__ . " error: LoadMap has been called without setting a map file.");	if (!$this->is_compiled)	  $this->CompileMap();	$this->map_ar = include($this->map_name . ".compiled");  }  # GetCoords returns the x,y coordinate of the array  # this function returns boolean false if the coordinates are out of bounds  function GetCoords($x, $y)  {	if ($y > count($this->map_ar) - 1)	  return false;	if ($x > count($this->map_ar[$y]) - 1)	  return false;	return $this->map_ar[$y][$x];  }}?>

Here is the example map I was using, save this as maptest.map:

.....................@.............***.......@........*****.@..@..........*****......@........*****..@.............***..........................^..................^^^.................^^.................^^.................^^.................^^^.................^^............~~....^......~.....~~~~.........~~~...~~~~~~........~~~~~~~~~~~~.........~~~~~~.~~~~..........~~~~...~~.......................

And here is an example script that uses it:

<?phpinclude "class.GameMap.php";$map = new GameMap("e:\\path\\to\\maptest.map");echo "\n0,0: " . $map->GetCoords(0, 0);echo "\n2, 11: " . $map->GetCoords(2, 11);echo "\n15, 3: " . $map->GetCoords(15, 3);echo "\n19, 19: " . $map->GetCoords(19, 19);echo "\n20, 10: " . $map->GetCoords(20, 10);echo "\n10, 20: " . $map->GetCoords(10, 20);?>

Once you run the test, you can see that a file will be created in the same folder as maptest.map called maptest.map.compiled. You can open that to see the static definition I was talking about, where it is just PHP code to define the array. It doesn't have line breaks to keep the file size as small as possible. The CompileMap method in the class creates that file.

Link to comment
Share on other sites

Bah!

[Wed Dec 06 20:10:52 2006] [error] [client 74.129.6.7] Allowed memory size of 8388608 bytes exhausted (tried to allocate 11796480 bytes)[Wed Dec 06 20:10:52 2006] [error] [client 74.129.6.7] Premature end of script headers: php-script
-.-sounds like its not so compiled :).
Link to comment
Share on other sites

OK, we need to figure out where the limit is being reached. Replace the CompileMap method with this one:

  # CompileMap will write a PHP file containing a static array declaration  function CompileMap()  {	if ($this->map_name == "")	  die ("Class " . __CLASS__ . " error: CompileMap has been called without setting a map file.");	echo "Opening the map file " . $this->map_name . "<br>";	echo "Memory used: " . memory_get_usage() . " bytes<br>";	# get the contents of the map file	$contents = file_get_contents($this->map_name);	# split up into lines	$lines = explode("\n", $contents);	echo "<br>Map file contains " . count($lines) . " lines<br>";	echo "Memory used: " . memory_get_usage() . " bytes<br>";	# open the compiled map file for writing and truncate it	if (!$fh = fopen($this->map_name . ".compiled", "wb+"))	{	  die ("Class " . __CLASS__ . " error: Could not open map file for writing (" . $this->map_name . ".compiled).");	}	# write the opening PHP and declaration	$str = "<" . "?php\n" . "\$_a = array();\n";	fwrite($fh, $str);	echo "<br>Opened the file for writing<br>";	echo "Memory used: " . memory_get_usage() . " bytes<br><br>";	# iterate through the lines	for ($i = 0; $i < count($lines); $i++)	{	  # create a new temp array for the line	  $str = "\$_b = array();";	  fwrite($fh, $str);	  # iterate through the characters on the line	  for ($j = 0; $j < strlen($lines[$i]); $j++)	  {		# add the current character to the temp line array		$str = "\$_b[] = \"{$lines[$i][$j]}\";";		fwrite($fh, $str);	  }	  # add the temp line array to the base array	  $str = "\$_a[] = \$_b;";	  fwrite($fh, $str);	  echo "Line {$i} processed, memory used: " . memory_get_usage() . "<br>";	}		# return the base array and end the PHP	$str = "\nreturn \$_a;\n?" . ">";	fwrite($fh, $str);	fclose($fh);		echo "<br>File completed<br>";	echo "Memory used: " . memory_get_usage() . " bytes<br>";  }

Post a chat link if you want to chat.

Link to comment
Share on other sites

Use gmail for chat?Looks like it worked..http://www.excibius.com/excibius/skills/wi...ess/maptest.phpSo, went from 8,352,616 to 820,496 bytes apparently. Or maybe that was just for writing it! I dont know, you check it out.EDIT: odd, tell me whats wrong with this:

Line 264 processed, memory used: 820456Line 265 processed, memory used: 820496Line 266 processed, memory used: 820496Line 267 processed, memory used: 820496Line 268 processed, memory used: 820496
The memory stays the same from 265 on.
Link to comment
Share on other sites

Does the .compile file get written? I guess it makes sense to use a constant memory, because new variables do not get created each loop. The same variables get re-used, and the size of each variable stays constant, so it would make sense to use a constant memory footprint. The big different between scripts would be the size of the map you are trying to load in the first place, because it does read the entire thing in at once.That gives me an idea. Maybe instead of using file_get_contents, it can be modified to get 1 line at a time from the file and do a line-by-line read/write. That would cut down significantly on the memory demands, it would have 2 open file handles and one line at a time in memory instead of the entire source file PLUS an array of the lines. In fact, I forgot about that, so after we split up the lines, let's go ahead and de-allocate the other variable. So find this chunk in the CompileMap method and rename $content to $lines:

	# get the contents of the map file	$lines = file_get_contents($this->map_name);	# split up into lines	$lines = explode("\n", $lines);

That way we recycle the variable. But I think line-by-line is the way to go. I'll try to find a minute today to make that change.

Link to comment
Share on other sites

Thanks to steve we got it all figured out! If you want to see the whole class and how to use it this is how:

<?phpclass GameMap{  # declare properties  var $map_ar;  var $map_name;  # constructor  function GameMap($name = "")  {	# create an empty array	$this->map_ar = array();	$this->map_name = "";	# if a name was given, call the SetMap method	if ($name != "")	  $this->SetMap($name);  }  # SetMap will check for the file, set the map_name property,  # and call the CheckCompiled and LoadMap functions  function SetMap($name)  {	if (file_exists($name))	  $this->map_name = $name;	else	  die ("Class " . __CLASS__ . " error: the map file does not exist.");  }  # GetCoords returns the x,y coordinate of the array  # this function returns boolean false if the coordinates are out of bounds  function GetCoords($x, $y)  {	$x--; $y--;	if ($x < 0 || $y < 0) return false;	if ($this->map_name == "")	  die ("Class " . __CLASS__ . " error: GetCoords has been called without setting a map file.");	  	# open the map file for reading	if (!$fh = fopen($this->map_name, "rb"))	{	  die ("Class " . __CLASS__ . " error: Could not open map file for reading (" . $this->map_name . ").");	}	$y_found = false;	$retval = false;	$nr = 0;	while (!@feof($fh) && !$y_found)	{	  # get line number $nr	  $line = trim(fgets($fh));	  if ($nr == $y)	  {		$y_found = true;		break;	  }	  else		$nr++;	}	if ($y_found)	{	  if (strlen($line) > $x)		$retval = $line[$x];  # get character number $x	}	fclose($fh);	return $retval;  }}?>

<?phpinclude "class.GameMap.php";$map = new GameMap("file name");echo $map->GetCoords(1,2);echo "<br />".memory_get_usage();?>

:)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...