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

Discussion in 'Scripts, 3rd Party Apps, and Programming' started by jkmaster9918, Apr 7, 2010.

  1. jkmaster9918

    jkmaster9918 New Member

    Messages:
    2
    Likes Received:
    0
    Trophy 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)==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();
    ?>
     
  2. misson

    misson Community Paragon Community Support

    Messages:
    2,572
    Likes Received:
    72
    Trophy 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_ERRMODEPDO::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: Apr 8, 2010
  3. jkmaster9918

    jkmaster9918 New Member

    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    I thought that that might be the problem. I'll try this type of thing and see if it works.
     

Share This Page