# foreach loop too slow?

I have a nested array that returns objects which are then traversed to retrirve the ids, which are then used to retrieve another array, which is traversed and the values returned are echoed out.

The problem is this seems to take ages in the browser to work across. How do I go about speeding this up?

This is the first function:

 /**
* Get a page of Campaigns
* @param string $page - url to page of campaigns, default is first page * @return array - array of Campaign objects and a link to the next page if one exists */ public function getCampaigns($page=null){
$page = ($page) ? $this->CTCTRequest->baseUri.$page : $this->uri;$campaignsCollection = array('campaigns' => array(), 'nextLink' => '');
$response =$this->CTCTRequest->makeRequest($page, 'GET');$parsedResponse = simplexml_load_string($response['xml']); foreach ($parsedResponse->entry as $entry){$campaignsCollection['campaigns'][] = new Campaign(Campaign::createOverviewStruct($entry)); }$campaignsCollection['nextLink'] = Utility::findNextLink($parsedResponse); return$campaignsCollection;
}


This is the second function:

/**
* Get detailed Campaign object
* @param string $url - url of a Campiagn * @return Campaign */ public function getCampaignDetails($url){
$response =$this->CTCTRequest->makeRequest($url, 'GET');$parsedReturn = simplexml_load_string($response['xml']); return new Campaign(Campaign::createStruct($parsedReturn));
}


This is the code that traverses both of these and returns my values:

<?php
/*
*
*
*grab the  Campaign array
*
*
*/
$getallCampaigns =$ConstantContact->getCampaigns(false);
?>
<table class="CTCTtable">
<tr>
<th>Campaign Name</th>
<th>Date</th>
<th>Status</th>
<th>Sent#</th>
<th>Opens</th>
<th>Clicks</th>
<th>Bounces</th>
<th>Forwards</th>
<th>OptOuts</th>
<th>SpamReports</th>
</tr>
<?php
foreach ($getallCampaigns as$tableName => $tableData) { // Loop outer array foreach ($tableData as $row) { // Loop table rows$originalDate = $row->campaignDate;$newDate = date("d-m-Y", strtotime($originalDate)); //get campaign details$getallCampaignevents = $ConstantContact->getCampaignDetails($row);
//$getallCampaignsends =$ConstantContact->getCampaignSends($row); // //echo$getallCampaignevents->name;
echo '<tr>';
echo '<td><a title="'.$getallCampaignevents->name.'"href="'.$getallCampaignevents->id.'">'.$getallCampaignevents->name.'</a></td>'; echo '<td>'.$newDate.'</td>';
echo '<td>'.$getallCampaignevents->status.'</td>'; echo '<td>'.$getallCampaignevents->campaignSent.'</td>';
echo '<td>'.$getallCampaignevents->campaignOpens.'</td>'; echo '<td>'.$getallCampaignevents->campaignClicks.'</td>';
echo '<td>'.$getallCampaignevents->campaignBounces.'</td>'; echo '<td>'.$getallCampaignevents->campaignForwards.'</td>';
echo '<td>'.$getallCampaignevents->campaignOptOuts.'</td>'; echo '<td>'.$getallCampaignevents->campaignSpamReports.'</td>';
echo '</tr>';
// var_dump($getallCampaignevents); } } ?> </table>  Here is an example of the first returned array:  array(2) { ["campaigns"]=> array(50) { [0]=> object(Campaign)#68 (48) { ["name"]=> string(26) "*****************************" ["id"]=> string(74) "***********************************************" ["link"]=> string(44) "************************" ["status"]=> string(4) "Sent" ["campaignDate"]=> string(24) "2013-12-05T21:28:07.330Z" ["urls"]=> array(0) { } } [1]=> object(Campaign)#68 (48) { ["name"]=> string(26) "*****************************" ["id"]=> string(74) "***********************************************" ["link"]=> string(44) "************************" ["status"]=> string(4) "Sent" ["campaignDate"]=> string(24) "2013-12-05T21:28:07.330Z" ["urls"]=> array(0) { } } }  This is the second returend array:  object(Campaign)#64 (48) { ["name"]=> string(26) "*************" ["id"]=> string(74) "***************" ["link"]=> string(44) "************************" ["status"]=> string(4) "Sent" ["campaignDate"]=> string(24) "2013-12-05T21:28:07.330Z" ["lastEditDate"]=> string(24) "2013-12-02T14:52:13.629Z" ["lastRunDate"]=> string(24) "2013-12-05T21:28:07.327Z" ["campaignSent"]=> string(2) "13" ["campaignOpens"]=> string(1) "8" ["campaignClicks"]=> string(1) "5" ["campaignBounces"]=> string(1) "0" ["campaignForwards"]=> string(1) "0" ["campaignOptOuts"]=> string(0) "" ["campaignSpamReports"]=> string(0) "" ["subject"]=> string(33) "Offers, and your feedback please!" ["fromName"]=> string(18) "***************" ["campaignType"]=> string(5) "STOCK" ["hiveStatus"]=> string(0) "" ["archiveUrl"]=> string(0) "" } object(Campaign)#56 (56) { ["name"]=> string(26) "*************" ["id"]=> string(74) "***************" ["link"]=> string(44) "************************" ["status"]=> string(4) "Sent" ["campaignDate"]=> string(24) "2013-12-05T21:28:07.330Z" ["lastEditDate"]=> string(24) "2013-12-02T14:52:13.629Z" ["lastRunDate"]=> string(24) "2013-12-05T21:28:07.327Z" ["campaignSent"]=> string(2) "13" ["campaignOpens"]=> string(1) "8" ["campaignClicks"]=> string(1) "5" ["campaignBounces"]=> string(1) "0" ["campaignForwards"]=> string(1) "0" ["campaignOptOuts"]=> string(0) "" ["campaignSpamReports"]=> string(0) "" ["subject"]=> string(33) "" ["fromName"]=> string(18) "***************" ["campaignType"]=> string(5) "STOCK" ["hiveStatus"]=> string(0) "" ["archiveUrl"]=> string(0) "" }  I'm using Constant Contact's OAuth's API with this PHP wrapper to return these arrays, which can be found here. ## 1 Answer It takes "ages" because it's having to do requests out to the Internet itself, as can be seen here $response = $this->CTCTRequest->makeRequest($url, 'GET');
$parsedReturn = simplexml_load_string($response['xml']);


These requests will quickly dominate the performance of your code. You should go through your code carefully to see where it's making requests, and see if you can eliminate some of them, say, by caching results or batching requests.

Currently you have (at least) 1 + n requests made by the loop, where n is the number of iterations. No wonder it is slow!

• how do i go about caching the results? – vimes1984 Dec 8 '13 at 22:04
• If you own the site in question, getting the data to be stored in a database is probably the way to go. Otherwise, do the request to the Internet and store the result locally (in a database) only if you've not done that exact same request before, and if you have done that request before you can avoid the request by looking up what happened last time in your database. – Matt Dec 9 '13 at 1:51