Jump to content

ForEach help


tommyinnn

Recommended Posts

Can someone please help me with this code? I think this would need to be a foreach command - but not sure

 

It's for Shoutcast, it displays the IP address of each listener - it works but I need to split the IP's up

 

$shoutcast_data['hostname']  --- this displays each Ip address, but without line break, I need to split them up

 

Have tried

echo $shoutcast_data['hostname'] . '<br>';

 

But it lists the address as

56.49.987.5687.564.34.55 

 

I need

56.49.987.56

87.564.34.55 

 

 

Have tried several foreach examples also with no luck, it that what I need to be looking at? Thanks for any help!

 

 

 

 

Here is the complete code if any1 wants it.

<?php
error_reporting(0);
define ("DEBUG", "0");
$shoutcast_host = '<IP ADDRESS HERE>';  // SHOUTcast station url
$shoutcast_port = '<PORT HERE>';      // SHOUTcast station port number
$shoutcast_password = '<PASSWORD HERE>';  // SHOUTcast password
$shoutcast_url = "http://" . $shoutcast_host . ':' . $shoutcast_port . "/listen.pls";
$fsock_time_out = 1;
$fsock_error_number = 0;
$fsock_error_text = "";
$shoutcast_data = array('streamstatus' => '',
                       'currentlisteners' => '', 
                        'maxlisteners' => '',
					'useragent' => '',
					'underruns' => '',
					'connecttime' => '',
					'pointer' => '',
					'uid' => '',
                        'hostname' => '');
$shoutcast_xml = "";
global $shoutcast_data, $shoutcast_xml_element;
if (!function_exists('startElement')) {
  function startElement($parser, $name, $attrs) {
      global $shoutcast_xml_element;
      // track which xml element is being parsed
      $shoutcast_xml_element = strtolower($name);
  }
}
if (!function_exists('endElement')) {
  function endElement($parser, $name) {
      global $shoutcast_xml_element;
      // forget which xml element was being parsed
      $shoutcast_xml_element = '';
  }
}
if (!function_exists('handleData')) {
  function handleData($parser, $data) {
      global $shoutcast_data, $shoutcast_xml_element;
      $shoutcast_data[$shoutcast_xml_element] .= $data;
  }
}
if (!function_exists('defaultHandler')) {
  function defaultHandler($parser, $data) {}
}
$shoutcast_fp = fsockopen($shoutcast_host,
                          $shoutcast_port, 
                          $fsock_error_number,
                          $fsock_error_text,
                          $fsock_time_out);
if($shoutcast_fp) {
    // socket connection is established, so the station is on-line
    // set 1 second timeout for communication with the station
    // stream_set_timeout($shoutcast_fp, 1);
    
    // build a string containing an HTTP request to your SHOUTcast server
    $shoutcast_httpreq = "GET /admin.cgi?pass=$shoutcast_password&mode=viewxml
      HTTP/1.0\r\nUser-Agent: SHOUTcast Song Status (Mozilla Compatible)\r\n\r\n";
    // send HTTP request to shoutcast server
    fputs($shoutcast_fp, $shoutcast_httpreq);
    // read entire xml output stream
    while(!feof($shoutcast_fp)) {
        $shoutcast_xml .= fgets($shoutcast_fp, 1000);
    }
  
    // close the socket now we no longer need it
    fclose($shoutcast_fp);
    // if we have got some XML back  then we need to strip away some
    // stuff that we don't need  
    if ($shoutcast_xml != '')
        $shoutcast_xml = strstr($shoutcast_xml, '<SHOUTCASTSERVER>');
    // create an instane of the EXPAT XML parser
    $xml_parser = xml_parser_create();
    // set element start and end element handler functions
    xml_set_element_handler($xml_parser, 'startElement', 'endElement');
    // set character data handler function
    xml_set_character_data_handler($xml_parser, 'handleData');
  xml_set_default_handler($xml_parser, 'defaultHandler');
  
    // activate the XML parser
  $parsed = xml_parse($xml_parser, $shoutcast_xml, 1);
    // some debugging code
    if (DEBUG) {
        echo $shoutcast_xml;
        print_r ($shoutcast_data);
    }
    // check that the parsing operation worked correctly
    if ($parsed) {
        // it worked, so report the station status
        if ($shoutcast_data['streamstatus'] == '1') {
    


foreach($files as $file){ 
    $xml = simplexml_load_file($file); 
    XMLToArrayFlat($xml, $xmlarray, $file.':', true); 
} 




 echo '<p>Current listeners: ';
        echo $shoutcast_data['currentlisteners'];
        echo ' (only ';
        echo $shoutcast_data['maxlisteners'];
        echo ' allowed).</p>';
	echo '<BR>';
	echo '<BR>';

	echo '<p>IP: ';
        echo $shoutcast_data['hostname'];
	echo '<BR>';
	echo $shoutcast_data['currentlisteners'];

	echo '<BR>';
	echo $shoutcast_data['useragent'];

	echo '<BR>';
	echo $shoutcast_data['underruns'];

	echo '<BR>';
	echo $shoutcast_data['connecttime'];

	echo '<BR>';
	echo $shoutcast_data['pointer'];

	echo '<BR>';
	echo $shoutcast_data['uid'];




	  
        echo '</p>';
	        
               if (intval($shoutcast_data['currentlisteners']) 
             < intval($shoutcast_data['maxlisteners'])) {
            
           
        } else {
           
        }
        } else {
            // no streaming content is available
          
        }
        
    }
    else {
        // parsing failed
      if (DEBUG) {
          echo 'XML Parser reported the following error:' . '<br />';
          echo xml_error_string(xml_get_error_code($xml_parser)) . ' in line ';
          echo xml_get_current_line_number($xml_parser) . '<br />';
      }
    }
    // the xml parser is no longer required
    xml_parser_free($xml_parser);
} else {
    // socket connection could not be established
    echo '<p>The station is offline.</p>';
}
?>

 

Link to comment
Share on other sites

well the code is too loing and im too lazy to read through all of it...but if $shoutcast_data['hostname'] is a multidimensional array, which it appears to be, you should be able to cycle through each IP like so

 

foreach($shoutcast_data['hostname'] as $value){
      print "$value <br />";
}

but since i didn't read your code I could be off, perhaps post the code that pertains to this specifically

Link to comment
Share on other sites

Thank you AyKay -- I did try this, and even searched for  "multidimensional array php" -- never heard about it.

 

 

Basically (I've deleted a lot of the code, but this will give you a idea how it works)

 

----

The script pulls the xml

 

$shoutcast_httpreq = "GET /admin.cgi?pass=$shoutcast_password&mode=viewxml

      HTTP/1.0\r\nUser-Agent: SHOUTcast Song Status (Mozilla Compatible)\r\n\r\n";

 

 

Then phases it --

 

 

$shoutcast_data = array('streamstatus' => '',  'currentlisteners' => '',  'maxlisteners' => '', 'useragent' => '', 'underruns' => '', 'connecttime' => '', 'pointer' => '', 'uid' => '', 'hostname' => '');

$shoutcast_xml = "";

 

 

Then prints it out

 

 

foreach($files as $file){

    $xml = simplexml_load_file($file);

    XMLToArrayFlat($xml, $xmlarray, $file.':', true);

}

echo '<h1>';    

echo $shoutcast_data['hostname'];

 

 

 

 

Link to comment
Share on other sites

hmm, alright, this is a little tricky, you cant use an explode here because there is no uncommon delimiter... you might be able to use preg_match here to grab each ip address separately...let's try

 

$subject = "56.49.987.5687.564.34.55"; //the haystack
$pattern = "~^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$~"; //needle
preg_match($pattern, $subject, $matches);
foreach($matches as $match){
      print "$match <br />";
}

 

 

Link to comment
Share on other sites

^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.

([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$

$subject = "56.49.987.5687.564.34.55"; //the haystack

$pattern = "~^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.

([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$~"; //needle

preg_match($pattern, $subject, $matches);

foreach($matches as $match){

      print "$match <br />";

}

Link to comment
Share on other sites

This XMLToArrayFlat() function scares me. No idea what it does, but the name screams information lost.

 

If I could see the raw XML output you want to parse, it should be possible to get what you want.

Link to comment
Share on other sites

Here is what the xml file looks like, this has a single listener

 

<SHOUTCASTSERVER>
<CURRENTLISTENERS>1</CURRENTLISTENERS>
<PEAKLISTENERS>3</PEAKLISTENERS>
<MAXLISTENERS>100</MAXLISTENERS>
<REPORTEDLISTENERS>1</REPORTEDLISTENERS>
<AVERAGETIME>92</AVERAGETIME>
<SERVERGENRE>pop</SERVERGENRE>
<SERVERURL>http://stationname.com</SERVERURL>
<SERVERTITLE>
2K22day.com - Playing the HOTTEST HITS !
</SERVERTITLE>
<SONGTITLE>
Young Jeezy - Let`s Get It: Thug Motivation 101 (CD & DVD) - Trap or Die
</SONGTITLE>
<SONGURL/>
<IRC>N/A</IRC>
<ICQ>N/A</ICQ>
<AIM>N/A</AIM>
<WEBHITS>31884</WEBHITS>
<STREAMHITS>692</STREAMHITS>
<STREAMSTATUS>1</STREAMSTATUS>
<BITRATE>64</BITRATE>
<CONTENT>audio/mpeg</CONTENT>
<VERSION>1.9.8</VERSION>
<WEBDATA>
<INDEX>8839</INDEX>
<LISTEN>0</LISTEN>
<PALM7>8861</PALM7>
<LOGIN>0</LOGIN>
<LOGINFAIL>21</LOGINFAIL>
<PLAYED>8718</PLAYED>
<COOKIE>0</COOKIE>
<ADMIN>3</ADMIN>
<UPDINFO>640</UPDINFO>
<KICKSRC>0</KICKSRC>
<KICKDST>0</KICKDST>
<UNBANDST>0</UNBANDST>
<BANDST>0</BANDST>
<VIEWBAN>0</VIEWBAN>
<UNRIPDST>0</UNRIPDST>
<RIPDST>0</RIPDST>
<VIEWRIP>0</VIEWRIP>
<VIEWXML>4791</VIEWXML>
<VIEWLOG>0</VIEWLOG>
<INVALID>11</INVALID>
</WEBDATA>
<LISTENERS>
<LISTENER>
<HOSTNAME>50.8.81.170</HOSTNAME>
<USERAGENT>MPEG OVERRIDE</USERAGENT>
<UNDERRUNS>0</UNDERRUNS>
<CONNECTTIME>1</CONNECTTIME>
<POINTER>0</POINTER>
<UID>691</UID>
</LISTENER>
</LISTENERS>
<SONGHISTORY>
<SONG>
<PLAYEDAT>1311770828</PLAYEDAT>
<TITLE>
Young Jeezy - Let`s Get It: Thug Motivation 101 (CD & DVD) - Trap or Die
</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311770536</PLAYEDAT>
<TITLE>Lil Wayne - Tha Carter III - Lollipop</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311770302</PLAYEDAT>
<TITLE>OutKast - Speakerboxxx/ The Love Below - Hey Ya</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311770084</PLAYEDAT>
<TITLE>Young Jeezy - The Recession - Who Dat</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311769865</PLAYEDAT>
<TITLE>Jim Jones - Pray IV Reign - We Fly High (Ballin`)</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311769630</PLAYEDAT>
<TITLE>Lupe Fiasco - The Cool - Hip-Hop Saved My Life</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311769428</PLAYEDAT>
<TITLE>Rick Ross - Port of Miami - Push It</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311769112</PLAYEDAT>
<TITLE>T.i. - Paper Trail - Swagger like us</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311768886</PLAYEDAT>
<TITLE>Mya - Fear of Flying - Case of the Ex</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311768717</PLAYEDAT>
<TITLE>
Three 6 Mafia - Most Known Unknown - Poppin My Collar
</TITLE>
</SONG>
</SONGHISTORY>
</SHOUTCASTSERVER>

Link to comment
Share on other sites

Sure - thanks so much for your help guys!

 

<SHOUTCASTSERVER>
<CURRENTLISTENERS>2</CURRENTLISTENERS>
<PEAKLISTENERS>3</PEAKLISTENERS>
<MAXLISTENERS>100</MAXLISTENERS>
<REPORTEDLISTENERS>2</REPORTEDLISTENERS>
<AVERAGETIME>64</AVERAGETIME>
<SERVERGENRE>pop, hip hop, rap</SERVERGENRE>
<SERVERURL>http://2k22day.com</SERVERURL>
<SERVERTITLE>
2K22day.com - Playing the HOTTEST HITS from 2000 till 2day!
</SERVERTITLE>
<SONGTITLE>Benzino - Redemption - Rock the Party</SONGTITLE>
<SONGURL/>
<IRC>N/A</IRC>
<ICQ>N/A</ICQ>
<AIM>N/A</AIM>
<WEBHITS>34563</WEBHITS>
<STREAMHITS>705</STREAMHITS>
<STREAMSTATUS>1</STREAMSTATUS>
<BITRATE>64</BITRATE>
<CONTENT>audio/mpeg</CONTENT>
<VERSION>1.9.8</VERSION>
<WEBDATA>
<INDEX>9563</INDEX>
<LISTEN>0</LISTEN>
<PALM7>9589</PALM7>
<LOGIN>0</LOGIN>
<LOGINFAIL>21</LOGINFAIL>
<PLAYED>9440</PLAYED>
<COOKIE>0</COOKIE>
<ADMIN>3</ADMIN>
<UPDINFO>708</UPDINFO>
<KICKSRC>0</KICKSRC>
<KICKDST>0</KICKDST>
<UNBANDST>0</UNBANDST>
<BANDST>0</BANDST>
<VIEWBAN>0</VIEWBAN>
<UNRIPDST>0</UNRIPDST>
<RIPDST>0</RIPDST>
<VIEWRIP>0</VIEWRIP>
<VIEWXML>5226</VIEWXML>
<VIEWLOG>0</VIEWLOG>
<INVALID>13</INVALID>
</WEBDATA>
<LISTENERS>
<LISTENER>
<HOSTNAME>50.9.81.180</HOSTNAME>
<USERAGENT>MPEG OVERRIDE</USERAGENT>
<UNDERRUNS>0</UNDERRUNS>
<CONNECTTIME>49</CONNECTTIME>
<POINTER>0</POINTER>
<UID>703</UID>
</LISTENER>
<LISTENER>
<HOSTNAME>173.132.159.43</HOSTNAME>
<USERAGENT>
WAFA/1.1.1 (Linux; Android 2.3.3; Winamp) Replicant/1.0
</USERAGENT>
<UNDERRUNS>0</UNDERRUNS>
<CONNECTTIME>3</CONNECTTIME>
<POINTER>1</POINTER>
<UID>704</UID>
</LISTENER>
</LISTENERS>
<SONGHISTORY>
<SONG>
<PLAYEDAT>1311786625</PLAYEDAT>
<TITLE>Benzino - Redemption - Rock the Party</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311786315</PLAYEDAT>
<TITLE>Young Jeezy - The Recession - My President`s Black</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311786076</PLAYEDAT>
<TITLE>Mike Jones - The American Dream - Drop & Gimme 50</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311785862</PLAYEDAT>
<TITLE>Lil Flip - Undaground Legend - Game Over</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311785660</PLAYEDAT>
<TITLE>T.i. - Paper Trail - I`m the King</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311785380</PLAYEDAT>
<TITLE>Nelly (Ft Kelly Rowland) - Dilemma - Dilemma</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311785328</PLAYEDAT>
<TITLE>Ludacris - Release Therapy - What`s Your Fantasy</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311784888</PLAYEDAT>
<TITLE>
Justin Timberlake - FutureSex / LoveSounds - What Goes Around
</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311784635</PLAYEDAT>
<TITLE>Snoop Dogg - Ego Trippin` - Life Of Da Party</TITLE>
</SONG>
<SONG>
<PLAYEDAT>1311784359</PLAYEDAT>
<TITLE>The Game - The Documentary - Dreams</TITLE>
</SONG>
</SONGHISTORY>
</SHOUTCASTSERVER>

Link to comment
Share on other sites

Well, the XML is badly coded.

 

<TITLE>Mike Jones - The American Dream - Drop & Gimme 50</TITLE>

should be

<TITLE>Mike Jones - The American Dream - Drop & Gimme 50</TITLE>

 

So any XML parser will fail. First, we need clean up this XML feed. I'll help you out with that.

Link to comment
Share on other sites

You'll have to find a balance between speed and efficiency. If the only special characters that might show up are &'s and double quotes, we can use a quick str_replace. Your XML doesn't have attributes, so we can simply use

 

$data = file_get_contents( $xml_url );
$data = str_replace(
array('&','"'),
array('&','"'),
$data
);

 

But if this changes, you may screw up attributes. If that's the case, we need to use RegEx to make sure we're only fixing text between tags. This is MUCH slower though.

 

$data = file_get_contents( $xml_url );
$exp = '/(<[^>]+>)([^<]+)/e';
echo preg_replace( $exp, "'\\1'.htmlspecialchars('\\2')", $data );

Link to comment
Share on other sites

No need to give me that.

 

Here's the code you want. I've used the slower RegEx method, but you can change that easily. As you can see, I've used PHP's DOMDocument to parse the XML, and grab only the attribute we want :D I then use a for loop to grab each one.

 

<?php

$data = file_get_contents( $xml_url );
$exp = '/(<[^>]+>)([^<]+)/e';
$data = preg_replace( $exp, "'\\1'.htmlspecialchars('\\2')", $data );

$xml = new DOMDocument;
$xml->loadXML( $data );

$listeners = $xml->getElementsByTagName( 'HOSTNAME' );

if( $listeners->length != 0 ) {
for( $i = 0; $i < $listeners->length; $i++ ) {
	echo $listeners->item($i)->nodeValue . '<br>';
}
} else {
echo 'No listeners';
}

?>

 

If there's anything you don't understand, check out the manual. If you still don't understand feel free to post here and I can explain.

Link to comment
Share on other sites

Thanks xyph -- been working on this for a while but still no luck, getting these errors

 

Warning: fopen(http://98.158.187.150:9998/admin.cgi?mode=viewxml&pass=PASSWORDHERE) [function.fopen]: failed to open stream: HTTP request failed! ICY 404 Resource Not Found in /home/jockey/public_html/control/test.php on line 3

 

Warning: DOMDocument::loadXML() [domdocument.loadxml]: Empty string supplied as input in /home/user/public_html/control/test.php on line 11

No listeners

 

 

Link to comment
Share on other sites

They seem to be detecting the user-agent, and throwing 404 headers when it's a bot accessing it. Jeez, first badly formatted XML, now this?! We can use cURL to get around te issue though.

 

<?php

$url = 'http://98.158.187.150:9998/admin.cgi?pass=*****&mode=viewxml';

$data = getWithCurl( $url );
$xml = new DOMDocument;
$xml->loadXML( $data );
$listeners = $xml->getElementsByTagName( 'HOSTNAME' );

if( $listeners->length != 0 ) {
for( $i = 0; $i < $listeners->length; $i++ ) {
	echo $listeners->item($i)->nodeValue . '<br>';
}
} else {
echo 'No listeners';
}

function getWithCurl($url) {
    $curl = curl_init();
    $header[] = "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
    $header[] = "Cache-Control: max-age=0";
    $header[] = "Connection: keep-alive";
    $header[] = "Keep-Alive: 300";
    $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
    $header[] = "Accept-Language: en-us,en;q=0.5";
    $header[] = "Pragma: ";
    $referer = "http://google.com";
    $browser = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092510 Ubuntu/8.04 (hardy) Firefox/3.0.3";

    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_USERAGENT, $browser);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    curl_setopt($curl, CURLOPT_REFERER, $referer);
    curl_setopt($curl, CURLOPT_AUTOREFERER, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_TIMEOUT, 30);
    curl_setopt($curl, CURLOPT_MAXREDIRS, 7);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);

    $data = curl_exec($curl);
    if ($data === false)
        $data = curl_error($curl);
    curl_close($curl);
    return $data;
}

?>

 

xyph -- there would not be any odd charters in this at all, it is the IP address I am after not the song title -- the special charters you were looking at were  were mp3 titles.

 

Yes, but ANY errors in ANY part of the XML file will cause a parser to fail. It reads the entire file. I realize you were just copy and pasting the data from the feed though, so I doubt those errors would show up in the real XML file.

Link to comment
Share on other sites

WOW, that did it -- thank you so much --

 

....you said "Yes, but ANY errors in ANY part of the XML file will cause a parser to fail" 

, that explains a lot

 

 

... you said, "Yes, but ANY errors in ANY part of the XML file will cause a parser to fail"

, this also explains a lot, I have always hear other's complain  about Shoutcast coding, everyone always said it was "messy coding", but to me Shoutcast seems to run well, very stable -- but now I can understand what this means "messy coding"

 

Thanks again xyph!

 

 

Link to comment
Share on other sites

That function pretty much makes the ShoutCAST server think your PHP script is Firefox running on Ubuntu. Pretty dumb that they aren't letting a bot scrape an XML feed, I thought that's what it was designed for :D

 

But Glad things could work. I hope you understand everything that was posted.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.