Help with speeding up php code

No errors but its not showing up properly. This is what it looks like:

Live User Streams:array(0) { }

Okay, the following works locally for me.

<?php
$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

<?php
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 (!empty($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=\\"" . htmlentities($json_array[0]['title']) . "\\" style='color: #C0C0C0'>";

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

echo "</span>";
?>

Now, since I don’t know what $viewers and $gameSTR refer to, so I can’t make those show the details you may want them to have without knowing their intention. I also temporarily added “riotgames” to the list of channels so I could at least see the results of a live channel.

For some reason it still isnt working properly =(. I copied exactly what you had into both and it came up with:

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, running out of ideas here, so here are TWO more solutions that work locally for me.

Solution #1: File #1

<?php
$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));
?>

Solution #1: File #2

<?php
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 (count($json_array) != 0 && isset($json_array[0]) && count($json_array[0]) != 0)
	{
		if ($json_array[0]['name'] == "live_user_{$channelName}")
			$live = true;
		else
			$live = false;

		$userLINK = "<a href=\\"http://www.twitch.tv/$channelName\\" target=\\"_blank\\" title=\\"" . htmlentities($json_array[0]['title']) . "\\" style='color: #C0C0C0'>";

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

echo "</span>";
?>

Solution #2: File #1

<?php
$chan = "";
$streams = array( "reckful", "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);
	}
}

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

Solution #2: File #2

<?php
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 (count($json_array) != 0 && isset($json_array[0]) && count($json_array[0]) != 0)
	{
		if ($json_array[0]->name == "live_user_{$channelName}")
			$live = true;
		else
			$live = false;

		$userLINK = "<a href=\\"http://www.twitch.tv/$channelName\\" target=\\"_blank\\" title=\\"" . htmlentities($json_array[0]->title) . "\\" style='color: #C0C0C0'>";

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

echo "</span>";
?>

Now the one thing that I think was holding you up, and myself for that matter was original File #1 in both solutions had $out = array(), which created a blank multi-dimensional array right off the bat, that caused confusion in the script and now that is resolved, so hopefully this works.

Good catch! I made a typo in my code and even if I looked at it several times now I couldn’t make out what could be wrong… The first element was empty array, which tripped up the code that followed. BTW, that’s why I strongly believe that E_NOTICE error reporting should be always enabled when developing any code - if it was enabled then php would immediately throw a notice error about uninitialised variable in that line and all would be clear.

If you change $out = array(); to $out = array(); then I suppose either my original code or cpradio’s should work fine.

cpradio, how is that supposed to work (solution #2):


if ($json_array[0]->name == "live_user_{$channelName}")

how do you expect $json_array[0] to be an object? The working code in the first post clearly indicates this is array not object. I doubt this will work.

It does work, because the json_decode is not forcing it to be an associative array, so php decodes it to an object, you can see the manual on json_decode to see that not passing “true” as the second parameter makes it an object.

I have E_NOTICE error reporting on and I still didn’t get any useful notice, just kept getting “Cannot use string offset as an array in /home/sglivest/public_html/livestreams2.php on line 16”.

Very odd, as I get notices on the other uninitialized variables.

Interesting, I’ve never used those additional json options so I wasn’t aware of them!

It’s odd and it turns out that php is not reporting E_NOTICE for $arr = value; if $arr is not initialised. It’s even documented:


$arr[key] = value;
$arr[] = value;
// key may be an integer or string
// value may be any value of any type

If $arr doesn’t exist yet, it will be created, so this is also an alternative way to create an array. This practice is however discouraged because if $arr already contains some value (e.g. string from request variable) then this value will stay in the place and may actually stand for string access operator. It is always better to initialize variable by a direct assignment.

To me it’s a bit inconsistent, I don’t know why arrays are an exception to the rule but this is php after all :slight_smile:

Yeah, its a great way to keep an OOP feel to your code if that is your preference :slight_smile:

Thanks for looking that up (I didn’t get a chance to yet), definitely is inconsistent, but at least that explains why I didn’t catch it right away.

Okay, so we have made progress. I can now see the format of the page and there are no errors. And it does load very quickly. But how long does it take to show up with a name? I have been live on my stream for 5 minutes and my name has not shown up yet. I have my name added to the list too.

Do you have a cronjob running the first file ever X minutes?

No, how would the command be written for this cron job?

Nvm, you just put the filename right? Which file are we running though, the one thats seeing if its live or the one thats projecting the live users.

You will need to put more than just the file name, something like php5 /path/to/filename.php

And you want the one that is seeing if its live. The one that projects the live users is to be used on your page.

I put php5 /home/sglivest/public_html/livestreams.php as the cron job set at every 3 minutes.

I have left my stream live for an hour and its still not showing up. AHHHHH!!! This is frustrating lol. I guess on the bright side theres no errors.

Do you have SSH access? As you may need to run that command to verify it is correct. Sometimes you have to point to the location of the php5 executable, such as, /usr/bin/php5. I’d also recommend asking your host where the php/php5 executable is located so you can easily run it.

Yes I do, although im not quite sure how to use it.

The file is not being ran in the cron job though so obviously im not tryping it in correctly yet. Im very, very sorry for being such a pest.

Okay, if you have SSH access, you need to download PuTTY

You will type in your domain name, use Port 22, and press Open
You will enter your username and password
Once logged in, type “whereis php5”, if it returns blank, then use “whereis php”

You are looking for a line similar to

php5: /usr/bin/php5 /etc/php5 /usr/lib/php5 ...

Or (if your whereis php returned a path)

php: /usr/bin/php /etc/php /usr/lib/php ...

The important piece is the one that contains /bin/

You will put the one that contains /bin/ in your cronjob, like so

/usr/bin/php5 /path/to/php/file.php

Or (if your whereis php returned a path)

/usr/bin/php /path/to/php/file.php

Okay, so now I can see 2 users on the list. But those users arent even online, and I haven’t seen my name (which I have been live for 10 minutes now). And I have my cron job set for 2 minutes.