Help with speeding up php code

Hi, I have this piece of code that checks if a live stream of a game is live or not. If it is live then it posts the players name who is streaming on a list where people can click to see his/her stream. The problem I am having is though is that it takes forever to load the page (probably because it takes so long to check the players streams). I was wondering if there was any way I could speed up the process and still keep what I want which is only the live users. Please, if you could answer with ease as I am still very new to this.

<?
$chan = "";
$streams = array( "meditor996", "malidude", "tacsecret", "izual155", "porkyhd", "tachydro#", "church_", "tainttubes", "kurimlinn", "TacvFOX", "tacpinkiepie", "dkrstarcraft", "chaoss tarcraft", "thepandrexlive", "zren89", "1soulfire", "sallvain", "sg_goldster", "adramelechii", "dragon", "dignitasselect", "sing_sing", "desrowfighting", "eghuk", "eg_idra", "rootcatz", "liquidsheth", "spanishiwa", "mtwdimaga", "whitera", "meditor996", "colqxc", "kraglord", "tsm_dyrus", "nyjacky", "crs_saintvicious", "tsm_theoddone", "mstephano", "protech", "tacmoose" );

echo '<br><br><font color="white"><b>Live User Streams:</b></font>';
foreach ($streams as &$i) {
$chan = "http://api.justin.tv/api/stream/list.json?channel=" . $i;
$json = @file_get_contents($chan);
$exist = strpos($json, 'name');
if($exist) {

$channelName = "$i"; //Set this to the channel name - all lowercase
$json_file = @file_get_contents("http://api.justin.tv/api/stream/list.json?channel={$channelName}", 0, null, null);
$json_array = json_decode($json_file, true);
if ($json_array[0]['name'] == "live_user_{$channelName}")
     $live = true;
else
     $live = false;

/*$gameSTR = "(" . $game . ")";*/
$userLINK = "<a href=\\"http://www.twitch.tv/$i \\" target=_blank title=$channelTitle style='color: #C0C0C0'>";


echo "<font style=tahoma color=white size=2>" . "<br>" . "&nbsp; " . "&nbsp; " . "&nbsp; " . $viewers . " " . $gameSTR . " " . $userLINK . $i . "</a>" . "</font>";



}

}
echo "</span>";

?>

Thanks in advance

I don’t think you can speed it up if you use your current approach of making a separate connection to api.justin.tv for each of those channels, this is guaranteed to be slow. Your hope could be in checking whether the stream’s API allows you receive information of all those users in a single request like this:

http://api.justin.tv/api/stream/list.json?channels=meditor996,malidude,tacsecret,

This would make a huge difference. If you can’t do this then you might display the list of channels with some empty space and use XMLHttpRequest via javascript to load information about each channel and update on the fly. It wouldn’t be faster but at least users would not have to wait so long to see the page.

Well i have seen another way which involves the same method of getting the stream but they would put the live users in txt page then retrieve it when they reload the page. Then it doesent have to check all the but every like 5 or 10 minutes. Im not exactly sure how to set it up though.

Also, is there any way I could use a caching method sort like the method stated above?

Or maybe make my script only check the live streams every 10 minutes rather than every time they load the page?

Any ideas on what I stated above?

Yes, you can use caching, I thought you needed very up-to-date data that’s why I ruled it out.

Make another php file in which you will load external data like you do it above except instead of outputting it to the browser store the data in a file. Then setup a cron job to run this script every 5 minutes - how you do it depends on your hosting, usually it’s done through the hosting’s admin panel. The last thing is to modify the page to display data from the file instead of loading external source.

Pardon me, but are you a third-party, or part of Justin.tv’s staff? If you are staff, I’d like to help, as I use the TardisBlue channel there. Contact me using one of the admin email from there. There may be some work involved in changing your existing scripts. Otherwise, I’d suggest contact them directly and ask what thier api is capable of handling. The script might not be setup to handle multile channels in a list as suggested above.

@Lemon Juice - Ok that seems somewhat simple. Is there any way you could give me an example of how that would be done? Like I said im not exactly fluent with any coding experience. If that is asking too much I would be willing to donate a small amount if it all works properly.

@Serenarules - Im a third party, not a part of Justin.tv’s staff.

Ok, here is something for you to play with, it’s untested so it can contain errors but it’s simple enough so you will be able to make it work - just in case php documentation is a very good resource to learn from!

This would be the script to be run every x minutes:


$chan = "";
$streams = array( "meditor996", "malidude", "tacsecret", "izual155", "porkyhd", "tachydro#", "church_", "tainttubes", "kurimlinn", "TacvFOX", "tacpinkiepie", "dkrstarcraft", "chaoss tarcraft", "thepandrexlive", "zren89", "1soulfire", "sallvain", "sg_goldster", "adramelechii", "dragon", "dignitasselect", "sing_sing", "desrowfighting", "eghuk", "eg_idra", "rootcatz", "liquidsheth", "spanishiwa", "mtwdimaga", "whitera", "meditor996", "colqxc", "kraglord", "tsm_dyrus", "nyjacky", "crs_saintvicious", "tsm_theoddone", "mstephano", "protech", "tacmoose" );

$out[] = array();

foreach ($streams as $channelName) {
  $chan = "http://api.justin.tv/api/stream/list.json?channel=" . $channelName;
  $json_file = @file_get_contents($chan);
  $exist = strpos($json_file, 'name');

  if($exist) {
    $out[$channelName] = $json_file;
  }
}

file_put_contents("channels.txt", serialize($out));

And the script to display the page:


echo '<br><br><font color="white"><b>Live User Streams:</b></font>';
$files_data = file_get_contents("channels.txt");
$json_files = unserialize($files_data);

foreach ($json_files as $channelName => $json_file) {

  $json_array = json_decode($json_file, true);

  if ($json_array[0]['name'] == "live_user_{$channelName}")
     $live = true;
  else
     $live = false;

  $userLINK = "<a href=\\"http://www.twitch.tv/$channelName\\" target=_blank title=$channelTitle style='color: #C0C0C0'>";

  echo "<font style=tahoma color=white size=2>" . "<br>" . "&nbsp; " . "&nbsp; " . "&nbsp; " . $viewers . " " . $gameSTR . " " . $userLINK . $channelName . "</a>" . "</font>";
}

echo "</span>";

Here at the end there are some varialbles like $channelTitle which are not defined and I have no idea where they come from so you will have to solve it somehow as you have access to all scripts.

You would set it up to run every 5 minutes by either setting up a cronjob (if on *nix server) or a scheduled task (if on a windows server). Most control panels will help you setup either. Just keep in mind you will need to either put the php5 or php executable in from of the script path (use absolute path)

Well I put everything in and its coming up with the following error:

Warning: json_decode() expects parameter 1 to be string, array given in /home/sglivest/public_html/livestreams2.php on line 16

This is line 16 on “livestreams2.php” : $json_array = json_decode($json_file, true);

Any idea?

put var_dump($json_file) immediately before that line and give us the output from that statement.

Parse error: syntax error, unexpected T_VARIABLE in /home/sglivest/public_html/livestreams2.php on line 18

Line 18: $json_array = json_decode($json_file, true);

Make sure you put a semi-colon after the var_dump($json_file); command (sorry, I left that out earlier).

Yea I didnt catch that either.

Now im getting : Warning: json_decode() expects parameter 1 to be string, array given in /home/sglivest/public_html/livestreams2.php on line 18 which is again: $json_array = json_decode($json_file, true);

And under that, I have all of this:
string(2405) "[{“embed_count”:“36”,“name”:“live_user_rootcatz”,“stream_count”:“59”,“category”:“gaming”,“format”:“live”,“channel_count”:141,“title”:“ROOTCatZ playin the GAMEZ”,“featured”:true,“site_count”:“23”,“abuse_reported”:false,“channel”:{“image_url_huge”:“http://static-cdn.jtvnw.net/jtv_user_pictures/rootcatz-profile_image-364f26660ea6d286-600x600.png",“producer”:true,“subcategory”:null,“category”:“gaming”,“image_url_tiny”:“http://static-cdn.jtvnw.net/jtv_user_pictures/rootcatz-profile_image-364f26660ea6d286-50x50.png”,“status”:"ROOTCatZ playin the GAMEZ”,“title”:“rootcatz”,“image_url_large”:"http://static-cdn.jtvnw.net/jtv_user_pictures/rootcatz-profile_image-364f26660ea6d286-300x300.png",“screen_cap_url_huge”:“http://static-cdn.jtvnw.net/previews/live_user_rootcatz-630x473.jpg”,“image_url_small”:“http://static-cdn.jtvnw.net/jtv_user_pictures/rootcatz-profile_image-364f26660ea6d286-70x70.png”,“category_title”:“Gaming”,“embed_enabled”:true,“image_url_medium”:“http://static-cdn.jtvnw.net/jtv_user_pictures/rootcatz-profile_image-364f26660ea6d286-150x150.png”,“timezone”:“America/Lima”,“id”:17901901,“screen_cap_url_large”:“http://static-cdn.jtvnw.net/previews/live_user_rootcatz-320x240.jpg”,“channel_url”:“http://www.justin.tv/rootcatz”,“subcategory_title”:null,“screen_cap_url_medium”:"http://static-cdn.jtvnw.net/previews/live_user_rootcatz-

Two techniques spring to mind that are maybe worth trying:

First:
On your page, create an empty DIV with a CSS position: relative; width:XXX; height:YYY;
Create another DIV just before </body> with CSS position: absolute;
Move the PHP live stream code check script inside this DIV
This will display the page and when the the tests are complete then display the results in the correct part of the page.

Second:
Assume the player is on the list and add the name to be clicked.
I assume when clicked two results are possible either on or off line so act accordingly.

Wouldent your first suggestion do the same thing my code is doing now just within a div? I need the entire process to be sped up somehow.

I cant necessarily guess if they are online or offline. The list has to be comprised of only live users that are streaming. When a visitor comes to my website then they will be able to click the live stream link bringing them to a page to watch their stream.

Try the following code:

$chan = ""; 
$streams = array( "meditor996", "malidude", "tacsecret", "izual155", "porkyhd", "tachydro#", "church_", "tainttubes", "kurimlinn", "TacvFOX", "tacpinkiepie", "dkrstarcraft", "chaoss tarcraft", "thepandrexlive", "zren89", "1soulfire", "sallvain", "sg_goldster", "adramelechii", "dragon", "dignitasselect", "sing_sing", "desrowfighting", "eghuk", "eg_idra", "rootcatz", "liquidsheth", "spanishiwa", "mtwdimaga", "whitera", "meditor996", "colqxc", "kraglord", "tsm_dyrus", "nyjacky", "crs_saintvicious", "tsm_theoddone", "mstephano", "protech", "tacmoose" ); 

$out[] = array(); 

foreach ($streams as $channelName) { 
  $chan = "http://api.justin.tv/api/stream/list.json?channel=" . $channelName; 
  $json_file = @file_get_contents($chan); 
  $exist = strpos($json_file, 'name'); 

  if($exist) { 
    $out[$channelName] = json_decode($json_file, true); 
  } 
} 

file_put_contents("channels.txt", serialize($out));  

and

echo '<br><br><font color="white"><b>Live User Streams:</b></font>'; 
$files_data = file_get_contents("channels.txt"); 
$json_files = unserialize($files_data); 

foreach ($json_files as $channelName => $json_array) { 

  if ($json_array[0]['name'] == "live_user_{$channelName}") 
     $live = true; 
  else 
     $live = false; 

  $userLINK = "<a href=\\"http://www.twitch.tv/$channelName\\" target=_blank title=$channelTitle style='color: #C0C0C0'>"; 

  echo "<font style=tahoma color=white size=2>" . "<br>" . "&nbsp; " . "&nbsp; " . "&nbsp; " . $viewers . " " . $gameSTR . " " . $userLINK . $channelName . "</a>" . "</font>"; 
} 

echo "</span>";

Fatal error: Cannot use string offset as an array in /home/sglivest/public_html/livestreams2.php on line 16

Line 16: if ($json_array[0][‘name’] == “live_user_{$channelName}”)

okay, add the var_dump($json_array); line again, and give me the output. I think we are getting closer now.

Fatal error: Cannot use string offset as an array in /home/sglivest/public_html/livestreams2.php on line 16

Line 16: if ($json_array[0][‘name’] == “live_user_{$channelName}”)

Use this, as it isn’t giving me the values I need to see.

echo '<br><br><font color="white"><b>Live User Streams:</b></font>'; 
$files_data = file_get_contents("channels.txt"); 
$json_files = unserialize($files_data); 

foreach ($json_files as $channelName => $json_array) { 

  var_dump($json_array);
die();
  if ($json_array[0]['name'] == "live_user_{$channelName}") 
     $live = true; 
  else 
     $live = false; 

  $userLINK = "<a href=\\"http://www.twitch.tv/$channelName\\" target=_blank title=$channelTitle style='color: #C0C0C0'>"; 

  echo "<font style=tahoma color=white size=2>" . "<br>" . "&nbsp; " . "&nbsp; " . "&nbsp; " . $viewers . " " . $gameSTR . " " . $userLINK . $channelName . "</a>" . "</font>"; 
} 

echo "</span>";