reportingsjr Posted December 6, 2006 Author Share Posted December 6, 2006 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 More sharing options...
justsomeguy Posted December 7, 2006 Share Posted December 7, 2006 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 More sharing options...
reportingsjr Posted December 7, 2006 Author Share Posted December 7, 2006 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 More sharing options...
justsomeguy Posted December 7, 2006 Share Posted December 7, 2006 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 More sharing options...
reportingsjr Posted December 7, 2006 Author Share Posted December 7, 2006 WOW, you are the best! So.. gabbly now? I need some explainin Link to comment Share on other sites More sharing options...
justsomeguy Posted December 7, 2006 Share Posted December 7, 2006 Make sure to reload, I've made some edits to it.I've got to go home, I'll try to chat in a little while. Link to comment Share on other sites More sharing options...
reportingsjr Posted December 7, 2006 Author Share Posted December 7, 2006 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 More sharing options...
justsomeguy Posted December 7, 2006 Share Posted December 7, 2006 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 More sharing options...
reportingsjr Posted December 7, 2006 Author Share Posted December 7, 2006 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: 820496The memory stays the same from 265 on. Link to comment Share on other sites More sharing options...
justsomeguy Posted December 7, 2006 Share Posted December 7, 2006 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 More sharing options...
reportingsjr Posted December 7, 2006 Author Share Posted December 7, 2006 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now