Brandon Turpy Brandon Turpy - 6 months ago 11
PHP Question

Get a XML list and return values with number of times listed

I am connecting to an XML file and trying to create a list that shows each value listed one time, followed by the number of times it is listed. So if the value shows in there 10 times, I want 1 entry with the # 10 by it.

I have everything working, but I can not seem to get it to update the number instead of adding a new entry to the list. Something is not correct, but I am not able to step through like I would in JS to test it. (This is in PHP by the way)

XML FILE (Simplified)- There are a lot more entries with many more 's per

<result>
but this should give an idea of the layout of the XML FILE

<results>
<result date="2016-05-17">
<row>
<label>www.url1.com</label>
</row>
<row>
<label>www.url2.com</label>
</row>
</result>
<result date="2016-05-19">
<row>
<label>www.url1.com</label>
</row>
</result>
</results>


PHP

$refferers = simplexml_load_file('https://url.com');

$refferer_urls = array( );
$refferer_html = '';

foreach ($refferers->result as $result) {
if ($result->row[0]) {
foreach($result->row as $refferal) {
$the_url = $refferal->label;
if( go_refferer_exsists( $refferer_urls, $the_url ) ) {
for($i = 0; $i < count($refferer_urls); $i++) {
if( $refferer_urls[$i]["url"] == $the_url ) {
$refferer_urls[$i]["quantity"]++;
}
}

} else {
array_push($refferer_urls, array(
"url" => $the_url,
"quantity" => 1,
));
}
}
}
}

for($i = 0; $i < count($refferer_urls); $i++) {

$refferer_html .= '<table>
<tr valign="top">
<td scope="row" width="75%">
<label for="tablecell"><strong>' . $refferer_urls[$i]["url"] . '</strong></label></td>
<td>' . $refferer_urls[$i]["quantity"] . '</td>
</tr>
</table>';
}

function go_refferer_exsists($the_array, $value) {

for($i = 0; $i < count($the_array); $i++) {
if ( $the_array[$i]["url"] == $value ) {
return true;
}
}

return false;
}


RETURNS

www.url1.com 1
www.url2.com 1
www.url1.com 1

Answer

Probably you'll find that you're having difficulty diagnosing the problem in your code because it's overly complex for what it's doing. You can simplify your logic a lot by indexing your $refferer_urls [sic] array by the URL itself, and just store the number of quantity as the value, e.g.:

foreach ($refferers->result as $result) {   
    if (!$result->row[0]) {
        continue;
    }

    foreach ($result->row as $refferal) {
        $the_url = (string) $refferal->label;
        // Initialize the key
        if (!array_key_exists($the_url, $refferer_urls)) {
            $refferer_urls[$the_url] = 0;
        }
        // Increment the count for it
        $refferer_urls[$the_url]++;
    }   
}

foreach ($refferer_urls as $url => $quantity) {
    $refferer_html .= '<table>
    <tr valign="top">
        <td scope="row" width="75%">
           <label for="tablecell"><strong>' . $url . '</strong></label></td>
         <td>' . $quantity . '</td>
    </tr>
    </table>';
}

Please note, I've also tweaked the spacing in your code and used continue as opposed to another level of indentation at the start of your first foreach. I've also swapped the while for a foreach in the second loop since you're looping an array straight through so it's cleaner to do it this way.

Example.