PHP script overloads server

jhmplondon
jhmplondon used Ask the Experts™
on
Hi guys,

I have customised version of OpenX ad server, I asked someone to add a code that will read content of meta keywords and depending on that will show accurate ads, it works great however after few days my servers needs restarting because the file takes 99% of server power (to be precise it's pretty good dedicated server).

So... below is a part responsible for extracting meta keywords and serving appropriate ads. Do you guys see something in code that could make it overload the server? Just to clarify again, its purpose is to extract only keywords, not the whole page content. I'm not php geek and i don't understand anything in this code.
$url = $GLOBALS['loc'];

	$fp = fopen( $url, 'r' );
	$content = "";

	while( !feof( $fp ) )
	{
		$buffer = trim(fgets($fp, 4096));
		$content .= $buffer;
	}

	$start = '<title>';
	$end = '<\/title>';

	preg_match( "/$start(.*)$end/s", $content, $match );
	$title = $match[ 1 ];
	

	$metatagarray = get_meta_tags( $url );
		
	$keywords = $metatagarray[ "keywords" ];
	
if(!empty($keywords)) {


		$temp = explode(",",$keywords);

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

		$add=explode(' ',trim($temp[$i]));

			if(sizeof($add)> 1)
			{

				$temp=array_merge($temp,$add);
	
			}
	
		}
	
		if(sizeof($temp)< 2)
		{
			$temp = explode(" ",$keywords);
		} 


		 $count = count($temp);

} else {

	$count = 0;

}







$con1 = mysql_connect($GLOBALS['_MAX']['CONF']['database']['host'],$GLOBALS['_MAX']['CONF']['database']['username'],$GLOBALS['_MAX']['CONF']['database']['password']);
mysql_select_db($GLOBALS['_MAX']['CONF']['database']['name'], $con1)or die("culnot select:".mysql_error());
$table_prefix = $GLOBALS['_MAX']['CONF']['table']['prefix'];

$keywordAds = array(); $nokeywordAds = array(); $k = 0; $nk = 0; 
$l = 0; $lastToSendAd = array();



	  $query = mysql_query("SELECT * FROM ".$table_prefix."ad_zone_assoc WHERE zone_id =".$_GET['zoneid']." ") or die("Error1".mysql_error());



	 if(mysql_num_rows($query)>0)
		{   
			while ($rowValues = mysql_fetch_assoc($query)) {	

				 $bannerQuery = mysql_query("SELECT * FROM oxm_keyword WHERE banner_id =".$rowValues['ad_id']." ") or die("Error2".mysql_error());

				if(mysql_num_rows($bannerQuery) > 0) {   

					$rowKeywords = mysql_fetch_assoc($bannerQuery);

						if(($count >= 1)) {

					    		for ($j = 0; $j < $count; $j++)
							{
									if ( strcmp (strtolower(trim($rowKeywords['keyword'])),strtolower(trim($temp[$j]))) == 0 )
									{
										 $lastToSendAd[$l] = $rowKeywords['banner_id'];
										 $l++;

									} 
							}

						} 

					
				 } else {

						$nokeywordAds[$nk] = $rowValues['ad_id'];
						$nk++;

				} 


			}

		}

	$keywordAdsCount =  sizeof($lastToSendAd);


	$nokeywordAdsCount =  sizeof($nokeywordAds);


	
	if($count >= 1) {

			if(!empty($lastToSendAd)) {


				if($keywordAdsCount > 1) {

					$banid=$lastToSendAd[rand(0,($keywordAdsCount-1))];

				} else {

					$banid=$lastToSendAd[0];
				}
					
					$ad = MAX_cacheGetAd($banid);

			} else {

				if($nokeywordAdsCount > 1) {

					$banid=$nokeywordAds[rand(0,($nokeywordAdsCount-1))];

				} else {

					$banid=$nokeywordAds[0];
				}
	
				$ad = MAX_cacheGetAd($banid);


			}


	} else {


				if($nokeywordAdsCount > 1) {

					$banid=$nokeywordAds[rand(0,($nokeywordAdsCount-1))];

				} else {

					$banid=$nokeywordAds[0];
				}
	
				$ad = MAX_cacheGetAd($banid);


	}

Open in new window



Thanks for help
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2011
Top Expert 2016
Commented:
If you don't understand the code, we may not be able to help you, so my first suggestion is to hire the PHP geek you need.  There are a lot of places that code could be spending non-value-added time.

It reads a file from a remote URL.  The remote URL could be slow.  There is probably no need to read the entire URL to get the contents of the <title> tag.  And after reading the URL, it reads the URL again with get_meta_tags().

It runs a query with SELECT * (always bad form to select all) with a WHERE clause.  Are the columns indexed correctly?  Has anyone looked at EXPLAIN SELECT?  Then it runs another query with SELECT *, this time inside a loop.  Probably the loop causes a lot of queries.  Some program design or table normalization might help here.

Does your application cache the keywords associated with each URL?  You might want to think about that.  You could have a separate asynchronous process that made periodic checks of the URLs and the keywords.  So instead of doing it all in real time, your real-time apps would be limited to serving the right ads, not doing a contemporaneous research project about which ads to serve.
Erdinç Güngör ÇorbacıPHP Development Team Leader

Commented:
Great questions

The ones from Ray Paseur  ... nothing less nothing more ...

But i want to take my shoot :)... i guess... Replacing line 80 with

$bannerQuery = NULL;

will speed up (Surely will not achieve what it has to and also -maybe- return many errors )

Query in a loop without a limit is a serious risk...

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial