8 Replies - 1670 Views - Last Post: 23 December 2009 - 06:44 PM Rate Topic: -----

#1 BMR777  Icon User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 41
  • Joined: 01-February 09

Speeding up this PHP file, that is lagging my server

Posted 21 December 2009 - 04:12 PM

Hello All,

I have a PHP file that is receiving a LOT of hits daily on my server (at least 50,000 + hits DAILY) and during peak traffic hours I can feel a noticeable (5+ second) lag when loading pages on my server as a result. The file in question is a dynamic image loader designed to take in an ID and select the appropriate image from the database and then output it using readfile to the user's browser with the correct content headers, etc gif, jpg, png, etc.

Here is the bulk of the file:

// We need to grab an adoptable ID

$id = $_GET["id"];
$id = preg_replace("/[^a-zA-Z0-9s]/", "", $id);
$id = secure($id);

// Check that ID exists and is valid

// Let's shut this down during times of peak server load...

$time = date(H);

// Keep this in place if we need to restart this, times are 15, 16 and 9

if($time != 15 and $time != 16){

if(is_numeric($id)){

// The ID appears to be valid, so double check...

$query = "SELECT * FROM ".$prefix."owned_adoptables WHERE aid='$id'";
$result = mysql_query($query);
$num = mysql_numrows($result);

//Loop out code
$i=0;
while ($i < 1) {

$[email protected]_result($result,$i,"aid"); //The adoptable's ID
$[email protected]_result($result,$i,"currentlevel");
$[email protected]_result($result,$i,"type");
$[email protected]_result($result,$i,"name");
$[email protected]_result($result,$i,"totalclicks");
$[email protected]_result($result,$i,"isfrozen");
$[email protected]_result($result,$i,"owner");

$i++;
}

if($aid == $id){

// The adoptable exists, so let's try and show the image

$usingimage = "no";

$image = getcurrentimage_local($id);

	// Let's see if the server has support for GD or not
	// Also to use fancy images the image must be a gif and fancy images must be enabled...

	$usegd = grabanysetting("gdimages");
	$imageinfo = @getimagesize($image);
	$imagemime = $imageinfo["mime"]; // Mime type of the image file, should be a .gif file...

	if(function_exists('imagegif') and $usegd == "yes" and $imagemime == "image/gif")
	{

	$usingimage = "yes"; //Turn the template system off

	// BEGIN NEW CODE

	list($width, $height, $type, $attr) = getimagesize($image); // The size of the original adoptable image

	// Begin the fancy outputs...

	// Lets create the new target image, with a size big enough for the text for the adoptable

	$newheight = $height + 72;

	if($newwidth < 250){
	$newwidth = 250;
	}
	else{
	$newwidth = $width;
	}

	  $img_temp = imagecreatetruecolor($newwidth, $newheight); 


	  $alphablending = true;  


		// Lets create the image and save its transparency  
	  $img_old = @imagecreatefromgif($image);  
	  imagealphablending($img_old, true);  
	  imagesavealpha($img_old, true);
   
	 // Lets copy the old image into the new image with  
	 // the given size  
	 ImageCopyResampled(  
		 $img_temp,  
		 $img_old,  
		 0, 0, 0, 0,  
		 $width,  
		 $height,  
		 $width,  
		 $height  
	 );  
   
	
	$textheight = $width + 2;

	$image = $img_temp;

	$bgi = imagecreatetruecolor($newwidth, $newheight);

	$color = imagecolorallocate($bgi, 51, 51, 51);


	$str1 = "Name: ".$name;
	$str2 = "Owner: ".$owner;
	$str3 = "Click Here to Feed Me!";
	$str4 = "More Adopts at:";
	$str5 = "www.".$domain;


	imagestring ($image, 2, 0, $textheight,  $str1, $color);
	imagestring ($image, 2, 0, $textheight + 13,  $str2, $color);
	imagestring ($image, 2, 0, $textheight + 26,  $str3, $color);
	imagestring ($image, 2, 0, $textheight + 42,  $str4, $color);
	imagestring ($image, 2, 0, $textheight + 55,  $str5, $color);

	$background = imagecolorallocate($image, 0, 0, 0);  
	  ImageColorTransparent($image, $background);  
 
	header("Content-Type: image/GIF");
	ImageGif ($image);
	imagedestroy($image);
	// imagedestroy($img_temp);
	imagedestroy($img_old);
	imagedestroy($bgi);

	}
	else{
	
	// We are going to try and get this image the old fashioned way...
	// Define a list of allowed file extentions...

	$extList = array();
	$extList['gif'] = 'image/gif';
	$extList['jpg'] = 'image/jpeg';
	$extList['jpeg'] = 'image/jpeg';
	$extList['png'] = 'image/png';

	//Define the output file type
	$contentType = 'Content-type: '.$extList[ $imageinfo['extension'] ];

	if($imageinfo['extension'] =! "image/gif" and $imageinfo['extension'] =! "image/jpeg" and $imageinfo['extension'] =! "image/png"){

	// The file type is NOT ALLOWED
	die("Hacking Attempt!");

	}
	else{

	// File type is allowed, so proceed
	// Try and read the file in

	$usingimage = "yes"; //Turn the template system off

	$status = "";

	header ($contentType);
	$status = readfile($image);

	if($status == "" or $status == "false" or $status == "FALSE"){

	// Reading the file failed, so show an error...	
	header ("text/plain");
	die("Readfile appears to be disabled on your host.");

	}
	


	} 

	}


}
else{

// Bogus ID

die("Invalid adoptable id specified!");


}
}
else{

// Bogus ID

die("Invalid adoptable id specified!");

}

}
else{

// Deal with high server load...

header("Content-Type: image/GIF");
readfile("highload.gif");

}

// **********************************************************************
// Begin Template Definition
// **********************************************************************

//Define our current theme
$file = $themeurl;

// Do the template changes and echo the ready template
$template = file_get_contents($file);

$template = replace(':ARTICLETITLE:',$article_title,$template);
$template = replace(':ARTICLECONTENT:',$article_content,$template);
$template = replace(':ARTICLEDATE:',$article_date,$template);

$template = replace(':BROWSERTITLE:',$browsertitle,$template);
$template = replace(':SITENAME:',$sitename,$template);

//Define our links
$template = replace(':LINKSBAR:',$links,$template);

//Get the content for the side bar...

$sidebar = getsidebar();
$template = replace(':SIDEFEED:',$sidebar,$template);

//Get the ad content...
$template = replace(':ADS:',$ads,$template);

//Get the slogan info
$template = replace(':SLOGAN:',$slogan,$template);


if($usingimage != "yes"){
echo $template; // Only echo the template if we are not showing an image... 
}



This file is receiving so many hits that on a VPS server with 512 MB RAM when this thing is active and receiving traffic it is dramatically slowing the server down. Any tips on optimizing this file or speeding things up?

EDIT: I should mention that the GD image library is not installed on this server, so the above code referencing GD is not used and just the readfile portion is used. :)

Thanks,
Brandon

This post has been edited by BMR777: 21 December 2009 - 04:25 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Speeding up this PHP file, that is lagging my server

#2 Jono20201  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 179
  • Joined: 07-July 09

Re: Speeding up this PHP file, that is lagging my server

Posted 21 December 2009 - 04:16 PM

An easy solution would be to get a better and faster server.
Was This Post Helpful? 0
  • +
  • -

#3 BMR777  Icon User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 41
  • Joined: 01-February 09

Re: Speeding up this PHP file, that is lagging my server

Posted 21 December 2009 - 04:19 PM

View PostJono20201, on 21 Dec, 2009 - 03:16 PM, said:

An easy solution would be to get a better and faster server.



I suppose that would be an easy solution, but servers unfortunately are expensive. This site is already utilizing 99% of the space on a VPS server, so it is basically the only site on the box. I'm also trying to figure out where the bottleneck is, either a PHP problem, a database problem, an Apache problem, or a combination. I don't want to upgrade if it won't do me any good. :)
Was This Post Helpful? 0
  • +
  • -

#4 moopet  Icon User is offline

  • binary decision maker
  • member icon

Reputation: 343
  • View blog
  • Posts: 1,189
  • Joined: 02-April 09

Re: Speeding up this PHP file, that is lagging my server

Posted 21 December 2009 - 05:28 PM

View PostJono20201, on 21 Dec, 2009 - 10:16 PM, said:

An easy solution would be to get a better and faster server.


What a fantastically bad answer! Anyway, moving on...

The code here is pretty bad. Tidy it up, cut out the dross that you don't use and remove the while() block and other bits that are not doing anything.
Just point the browser at the image file directly. You don't seem to have any legitimate reason for reading the image in and spitting it back out again in code, or for half the database stuff.

Something like this, given that I have no idea what secure() or getimage_local() do:
$id = isset($_GET['id']) ? $_GET['id'] : FALSE;
if (!$id || !is_numeric($id))
{
	die('invalid id');
}

$query = "SELECT * FROM ".$prefix."owned_adoptables WHERE aid='$id'";
$result = mysql_query($query);
if (mysql_numrows($result) != 1)
{
	die('invalid id');
}

// you don't ever use the stuff from the database past checking it exists, but if you did, this would be faster and cleaner:
// extract(mysql_fetch_array($result));

// assuming this bit gets the image from the id and returns FALSE on failure
$image = getcurrentimage_local($id);

if ($image)
{
	header("Location: {$image}");
}
else
{
	die('image not found');
}



in fact, since you only use the SQL to check the id exists in the database, you could change "SELECT *" for "SELECT aid" to get an extra nanoparticle of oomph.

This post has been edited by moopet: 21 December 2009 - 05:30 PM

Was This Post Helpful? 0
  • +
  • -

#5 AdaHacker  Icon User is offline

  • Resident Curmudgeon

Reputation: 463
  • View blog
  • Posts: 820
  • Joined: 17-June 08

Re: Speeding up this PHP file, that is lagging my server

Posted 21 December 2009 - 06:06 PM

One quick and easy thing would be to check that your database table has an index on 'aid'. If not, adding one should help (assuming the database is a bottleneck).
Was This Post Helpful? 0
  • +
  • -

#6 BMR777  Icon User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 41
  • Joined: 01-February 09

Re: Speeding up this PHP file, that is lagging my server

Posted 22 December 2009 - 01:54 PM

Thanks for the help. :)

@moopet - The reason I use readfile instead of a header redirect is that the outputted images will be used in places such as forum signatures and such. Will using a header redirect work if the image is to be embedded in another page or will I get a headers already sent error?

@AdaHacker - I have aid set as a primary key, which I believe automatically creates an index on it as well, correct?

Thanks :)
Was This Post Helpful? 0
  • +
  • -

#7 moopet  Icon User is offline

  • binary decision maker
  • member icon

Reputation: 343
  • View blog
  • Posts: 1,189
  • Joined: 02-April 09

Re: Speeding up this PHP file, that is lagging my server

Posted 23 December 2009 - 04:39 PM

View PostBMR777, on 22 Dec, 2009 - 07:54 PM, said:

@moopet - The reason I use readfile instead of a header redirect is that the outputted images will be used in places such as forum signatures and such. Will using a header redirect work if the image is to be embedded in another page or will I get a headers already sent error?


This file is called as part of a separate request from the browser. You won't get any header errors unless getimage_local() outputs anything, which I doubt. Should be ok.
Was This Post Helpful? 1
  • +
  • -

#8 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon


Reputation: 6996
  • View blog
  • Posts: 14,635
  • Joined: 16-October 07

Re: Speeding up this PHP file, that is lagging my server

Posted 23 December 2009 - 05:46 PM

You're doing so many things in the same place...

You process and return an image. Or, you process a template; in an inefficient homegrown fashion. And sometimes that image is just text filler? The stuff after "$extList" doesn't make that much sense, since you don't seem to return contents.

You'd do well to do one thing for .php file. Learning how to use a function or two wouldn't hurt.

For the bit with verifying and validating the passed id, I'd start with something like this:
<?php
// redundant
// $id = $_GET["id"];
// $id = preg_replace("/[^a-zA-Z0-9s]/", "", $id);
// $id = secure($id);

// Check that ID exists and is valid
// Let's shut this down during times of peak server load...

// good job planning for failure?
// $time = date(H);
// Keep this in place if we need to restart this, times are 15, 16 and 9
// if($time != 15 and $time != 16){
//if(is_numeric($id)){

//Loop out code
// $i=0; // meaningless
//while ($i < 1) { // meaningless
	// we'll do this better in a moment
	// $[email protected]_result($result,$i,"aid"); //The adoptable's ID
	// $i++;  // meaningless
// }

// get a row for the id
$row = get_owned_adoptables_row($_GET["id"]);

// if you didn't get a row, you're done
if (is_null($row)) { die("Invalid adoptable id specified!"); }

// if($aid == $id){ // redundant, you either got the row or not
// The adoptable exists, so let's try and show the image
$usingimage = "no";
$image = getcurrentimage_local($row['aid']);
//...

function get_owned_adoptables_row($id) {
	if(is_numeric($id)) {
		// no quotes, it's numeric
		$sql = "SELECT * FROM ".$prefix."owned_adoptables WHERE aid=$id";
		$result = mysql_query($sql);
		if ($result) { 
			$row = mysql_fetch_assoc($result);
			if ($row) { return $row; }
		}
	}
	return NULL; // always return null if it's crap
}
?>


Was This Post Helpful? 0
  • +
  • -

#9 BMR777  Icon User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 41
  • Joined: 01-February 09

Re: Speeding up this PHP file, that is lagging my server

Posted 23 December 2009 - 06:44 PM

Thanks for the advise. I redesigned the file from scratch and cut out all but the necessary code. I was able to get a tremendous speed boost on the server as a result.

I realize now that there was a lot of garbage or extra code on the original file, but what I didn't realize is how much that all affected performance! It sure runs a lot faster with only two SQL queries than the many I had previously. :)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1