4
\$\begingroup\$

Testing on localhost, it takes a bit longer to get the results than I would like and gives me this PHP error:

Fatal error: Maximum execution time of 30 seconds exceeded

I am wondering if there is any way to stop that error from happening, as well as making my class faster to fetch results.

<?php

class MinecraftAPI 
{

    private function getAPI($type, $server)
    {
        $url = 'http://api.iamphoenix.me/' . $type . '/?server_ip=' . $server;
        $file = file_get_contents($url);
        $file = json_decode($file);
        if (property_exists($file, 'error')) {
            return false;
        }
        return $file;
    }

    /*
        Fetch Server Information for each server.
        APIs:
        http://api.iamphoenix.me/
     */

    private function statusCheck($server)
    {
        $status = $this->getAPI('status', $server);
        if ($status != false) {
            if ($status->status == 'true') {
                return true;
            }
            return false;
        }
    }

    public function getStatus($server)
    {
        $status = $this->getAPI('status', $server);
        if ($status != false) {
            if ($status->status == 'true') {
                return '<strong class="status-online"> Online :]</strong>';
            } elseif ($status->status == 'false') {
                return '<strong class="status-offline"> Offline :[</strong>';
            } else {
                return 'Not sure. Check the forums.';
            }
        }
    }

    public function getVersion($server)
    {
        if ($this->statusCheck($server) != false) {
            $version = $this->getAPI('version', $server);
            if ($version != false) {
                return '<span><strong>' . $version->version . '</strong></span>';
            } else {
                return false;
            }
        }
    }

    public function getPlayerCount($server)
    {
        if ($this->statusCheck($server) != false) {
            $playerCount = $this->getAPI('players', $server);
            if ($playerCount != false) {
                $playersOnline = $playerCount->players;
                $playersMax = $playerCount->players_max;
                if ($playersOnline == 0) {
                    return '
                    <span>Players Online: <strong>' . $playersOnline . '/' . $playersMax . '</strong>
                    <!-- <em class="empty-server">Server Depleted. Come fill it up!</em> --></span>';
                }
                return '<span>Players Online: <strong>' . $playersOnline . '/' . $playersMax . '</strong></span>';
            }
        }
    }

    public function getPlayers($server)
    {
        if ($this->statusCheck($server) != false) {
            $playersList = $this->getAPI('list', $server);
            if ($playersList != false && $playersList != "") {
                $players = explode(',', $playersList->players);
                if (is_array($players) && !empty($players)) {
                    foreach ($players as $player) {
                        if ($player !== '')  {
                            echo '<img data-tooltip class="has-tip" title="'.$player.'" src="https://minotar.net/avatar/'.$player.'/32">';
                        }
                    }
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
    }
}

// Initiate the class
$api = new MinecraftAPI();

// Define servers
$server = [
    'craftblock' => 'craftblock.me',
    'nanoblock' =>  'craftblock.me:25585',
    'chocoblock' => 'craftblock.me:25564'
];

HTML:

        <div class="server-info">
            <span>Status: <?php echo $api->getStatus($server['craftblock']); ?></span>
            <?php echo $api->getVersion($server['chocoblock']); ?>
            <?php echo $api->getPlayerCount($server['chocoblock']); ?>
        </div>
        <div class="players-online">
            <?php $api->getPlayers($server['craftblock']); ?>
        </div>
\$\endgroup\$
2
  • \$\begingroup\$ Have you consider use javascript ajax? If api.iamphoenix.me support CORS, it can be a good solution: you won't need php (at least, for these operations) and most important you can retry servers informations asynchronously \$\endgroup\$ Commented Dec 11, 2013 at 7:57
  • 1
    \$\begingroup\$ Maybe he wants to use PHP or he has too. Telling someone that the solution to their problem is to switch language is not a very good solution IMO. \$\endgroup\$
    – Max
    Commented Dec 11, 2013 at 8:29

1 Answer 1

1
\$\begingroup\$

I'd imagine your timeout is due to server lag, your code doesn't look to be something that should take anywhere near 30 seconds to execute. You might want to look at using set_time_limit() which has a pretty self explanatory name.

A few other quick observations if i may:

I'd separate out the HTML from the class logic more, in an MVC paradigm one would instantiate the class and assign the output of your methods to variables that you then include in your templates, this way if your class changes you don't need to change your view (the HTML) you can call completely different methods and your HTML can remain unchanged.

e.g. <?php echo $api->getPlayerCount($server['chocoblock']); ?>

Could simply be <?php print $playerCount; ?>

Some of your methods return HTML, you might want to consider methods that return just a value, for example

$status = $api->getStatus(); and use that in the HTML

I'd refactor getPlayers to not return HTML, rather the values and use limited logic in your template, something like (untested)

/**
* get players
* @return array players
*/
public function getPlayers($server)
{
   $players = array();
    if ($this->statusCheck($server) != false) 
    {
        $playersList = $this->getAPI('list', $server);
        if ($playersList != false && $playersList != "") 
        {
            $players = explode(',', $playersList->players);
        }     
    }
    return $players;
}

and in your template you could loop over players knowing it's always an array (but that sometimes it may have no values).

Finally be sure your use of != false and != "", for example, is giving the required results. You might want to look at using !== false just in case you're actually getting a value that equates to false in PHP (e.g. 0 or "").

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.