[PHP] Script terminating in middle of script for no reason

jkmaster9918

New Member
Messages
2
Reaction score
0
Points
0
My script is terminating in different places every time for no apparent reason. Does anyone have an idea why? You can find this Here. (Yes, some stuff may seem useless, but that is because I changed some stuff to figure out where it is dying.)
PHP:
<html>
<head>
<title>The Honor Guard Location Manager Torpia Display Page</title>
<link rel="stylesheet" type="text/css" href="balloontip.css" />

<script type="text/javascript" src="balloontip.js">

/***********************************************
* Rich HTML Balloon Tooltip- © Dynamic Drive DHTML code library (www.dynamicdrive.com)
* This notice MUST stay intact for legal use
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
***********************************************/

</script>
<style type='text/css'>
.good
{
    background-color: green;
    cell-padding: 5px;
}
.evil
{
    background-color: red;
    cell-padding: 5px;
}
</style>
</head>

<body>
<?php
    require("connect.php");
    $db_connection=new mysqli($server,$username,$password,$database);
    print "<table border=1>";
    for($y=1000;$y>0;$y--)
    {
        print "<tr>";
        for($x=-1000;$x<=1000;$x++)
        {
            $result=$db_connection->query("SELECT `V_type`,`Owner`,`village_name` FROM locations WHERE `Coord_X`=$x AND `Corrd_Y`=$y");
            if(is_bool($result))
            {
                $output="<td border=1>_placeholder</td>\n";
            }
            else
            {
                $loc_data=$result->fetch_assoc();
                $output="<a href='http://w1.torpia.com/tile/tile/$x/$y' rel='$x|$y'><td border=1 class='".$loc_data['V_type']."'>_placeholder</td></a><div class='balloonstyle' id='$x|$y'>".$loc_data['village_name']."- Owned by:".$loc_data['Owner']."(".$loc_data['V_type'].")</div>\n";
            }
            $placeholder="";
            if($x==0)
            {
                if(($y%100)==0)
                {
                    $placeholder="$y";
                }
                else
                {
                    $placeholder="|";
                }
            }
            $output=str_replace("_placeholder","$x|$y",$output);
            print $output;
        }
        print "</tr>";
        $db_connection->ping();
    }
    print "<tr>";
    for($x=-1000;$x<=1000;$x++)
    {
        $result=$db_connection->query("SELECT `V_type`,`Owner` FROM locations WHERE `Coord_X`=$x AND `Corrd_Y`=0");
        if(is_bool($result))
        {
            $output="<td>_placeholder</td>\n";
        }
        else
        {
            $loc_data=$result->fetch_assoc();
            $output="<a href='http://w1.torpia.com/tile/tile/$x/0' rel='$x|0'><td class='".$loc_data['V_type']."'>_placeholder</td></a><div class='balloonstyle' id='$x|0'>".$loc_data['village_name']."- Owned by:".$loc_data['Owner']."(".$loc_data['V_type'].")</div>\n";
        }
        $placeholder="";
        if(($x%100)==0 and $x!=0)
        {
            $placeholder="$x";
        }
        elseif($x==0)
        {
            $placeholder="+";
        }
        else
        {
            $placeholder="-";
        }
        $output=str_replace("_placeholder",$placeholder,$output);
        print $output;
    }
    print "</tr>";
    for($y=-1;$y>=-1000;$y--)
    {
        print "<tr>";
        for($x=-1000;$x<=1000;$x++)
        {
            $result=$db_connection->query("SELECT `V_type`,`Owner` FROM locations WHERE `Coord_X`=$x AND `Corrd_Y`=$y");
            if(is_bool($result))
            {
                $output="<td>_placeholder</td>\n";
            }
            else
            {
                $loc_data=$result->fetch_assoc();
                $output="<a href='http://w1.torpia.com/tile/tile/$x/$y' rel='$x|$y'><td class='".$loc_data['V_type']."'>_placeholder</td></a><div class='balloonstyle' id='$x|$y'>".$loc_data['village_name']."- Owned by:".$loc_data['Owner']."(".$loc_data['V_type'].")</div>\n";
            }
            $placeholder="";
            if($x==0)
            {
                if(($y%100)==0)
                {
                    $placeholder="$y";
                }
                else
                {
                    $placeholder="|";
                }
            }
            $output=str_replace("_placeholder",$placeholder,$output);
            print $output;
        }
        print "</tr>";
    }
    print "</table>";
    $db_connection->close();
?>
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
Always check for error conditions. This generally means checking the return value of functions that might fail and consulting any error status functions (e.g. mysqli::error and mysqli::errno).

PHP scripts are limited to 30 seconds of execution time (though this can be adjusted). Without knowing whether or not the script is generating any errors, I'd guess this is your problem.

Running a separate query for each x and y coordinate is killing your script. Firstly, you should use prepared queries when running the same query repeatedly so that the server doesn't need to parse the query each time. The mysqli driver offers mysqli::prepare to create prepared statements, but I find PDO offers an interface that's simpler to use. Secondly, you don't need to run that many queries. You can simply fetch all locations within the bounds, specifying the order of the results, and fetch the next location from the result as needed. To make it more readable, the code should be refactored into functions, classes and methods.

LocalDB.php:
PHP:
// defined in some other script to isolate user credentials. Auto-closing connections (based on 
//reference counting) left as an exercise for the reader
class LocalDB {
    static private $dbs = array();
    static function connect($db='dflt') {
        if (! isset($dbs[$db])) {
            $dbs[$db] = new PDO("mysql:host=localhost;dbname=$db", 'user', 'passwd');
            $dbs[$db]->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
        return $dbs[$db];
    }
}

PHP:
<?php
function placeholder($x, $y) {
    if ($x == 0) {
        if ($y == 0) {
            return '+';
        } elseif(($y % 100)==0) {
            return $y;
        } else {
            return '|';
        }
    } elseif ($y == 0) {
        if (($x % 100) == 0) {
            return $x;
        } else {
            return '-';
        }
    }
    return '';
}

function printLocation($x, $y, $thing) {
    $tile = placeholder($x, $y);
    if ($loc['x'] == $x && $loc['y'] == $y) {
        // the only legal children of a <tr> are <th> and <td>, 
        // so the other elements must go inside the table cell
        echo "<td class='$loc_data[V_type]'><a href='http://w1.torpia.com/tile/tile/$x/$y' rel='$x|$y'>$tile</a>
                 <div class='balloonstyle' id='$x|$y'>$loc[village_name]- Owned by: $loc_data[Owner]($loc_data[V_type])</div></td>\n";
        return True;
    } else {
        echo "<td>$tile</td>";
        return False;
    }
}

function nextLocation($locations) {
    $loc = $locQuery->fetch();
    if (False === $loc) {
        $loc = array('x' => -1001, 'y' => 1001);
    }
    return $loc;
}

function printMap($locations, $bounds) {
    ?><table border="1"><?php
      $loc = $locations->fetch();
      for ($y=$bounds[':top']; $y >= $bounds[':bottom']; --$y) {
        ?><tr><?php
          for ($x=$bounds[':left']; $x <= $bounds[':right']; ++$x) {
              if (printLocation($x, $y, $loc)) {
                  $loc = nextLocation($locations);
              }
          }
        ?></tr><?php
      }
    ?></table><?php
}

$bounds = array(':left' => -1000, ':right' => 1000, ':bottom' => -1000, ':top' => 1000);
try {
    $db=LocalDB::connection();
    $locQuery = $db->prepare('SELECT `V_type`,`Owner`,`village_name`, `Corrd_X` as x, `Coord_Y` as y
            FROM locations 
            WHERE `Coord_X` BETWEEN :left AND :right
              AND `Corrd_Y` BETWEEN :bottom AND :top
            ORDER BY Corrd_Y DESC, Corrd_X');
    $locQuery->setFetchMode(PDO::FETCH_ASSOC);
    $locQuery->execute($bounds);
    printMap($locQuery, $bounds);
} catch (PDOException $exc) {
    echo "I had a problem with the database, so I couldn't get the map. The problem has been logged, and we'll look into it.";
    error_log($exc);
    ...
}

Better still would be to create Map and Location classes that would hide the DB access. Display could be handled by those classes (with display methods), or you could have separate view classes to handle display. Set the fetch mode on the query to PDO::FETCH_CLASS and have the query return Location instances.

PHP:
class Location {
    function isAt($x, $y);
    function display();
}
class Map {
    protected $bounds_;
    // initialize a map with bounds given by $bounds
    function __construct__($bounds);
    // return all locations within the bounds
    protected function locations() {
        ...
        $locations->setFetchMode(PDO::FETCH_CLASS, 'Location', array());
        ...
    }
    function display();
}
 
Last edited:

jkmaster9918

New Member
Messages
2
Reaction score
0
Points
0
I thought that that might be the problem. I'll try this type of thing and see if it works.
 
Top