kreoton web development

Archive for the ‘Tutorials’ Category

XX ways to improve your PHP scripts execution time

Tuesday, February 12th, 2008

1. Many same kind of articles says that ‘require_once is expensive’. Ok we know that but what to do? Here is some ways how to include your php files not using ‘require_once’:

  • a) If you need to include object class file check if class not exists and then include:
  • <?php
    	if (!class_exists('testClass'))
    		require '../testClass.php';
    ?>
  • b) If you including simple script or template, define something in included file then check if it is not defined and then include it.
  • <?php
    //include.php
    define('INCLUDE', 1);
    #code ...
    ?>
    <?php
    //script where include file should be included
    if (!defined('INCLUDE'))
    	require 'include.php';
    ?>

2. If you can do not call functions in loop. Top programmers mistake is calling count() or sizeof() functions in for() loop. How to fix this you can find in every ‘XX ways to optimise your PHP code’ articles, but do not do like this:

<?php
	for ($i=0; $i<count($somearray); $i)
	{
		#code
	}
?>

You can fix this code like this:

<?php
	$counter = count($somearray);
	for ($i=0; $i<$counter; $i++)
	{
		#code
	}
?>

Or like this:

<?php
	for ($i=0, $counter = count($somearray); $i<$counter; $i++)
	{
		#code
	}
?>

Not only count() or sizeof() slows your code, I can say that every function called in loop slows yor script. Take a look at example bellow:

<?php
 
function build_home_path ()
{
	$sql = "SELECT value FROM settings WHERE key = 'path' LIMIT 1";
	$res = mysql_query($sql);
	$row = mysql_fetch_assoc($res);
	return $row['value'];
}
 
//build menu
$menu_items = array('home'=>'Home Page', 'about'=>'About Page');
foreach ($menu_items as $path => $title)
{
	echo '<li><a href="'.build_home_path().'/'.$path.'">'.$title.'</a></li>';
}
 
?>

How you see this code is absolutly good, and works fine, but can it be a little more faster? Yes it can be just look at build_home_path() function call. Function build_home_path() is called every loop interation, thats no good because it do just one thing it gets home path ( like http://www.kreoton.net/). Here is solution how to fix it:

<?php
//we can rewrite our loop contents in this way
$menu_items = array('home'=>'Home Page', 'about'=>'About Page');
$home_path = build_home_path();
foreach ($menu_items as $path => $title)
{
	echo '<li><a href="'.$home_path.$path.'">'.$title.'</a></li>';
}
?>

Thats all for this time come back for part 2.

PHP free eBooks

Thursday, September 6th, 2007

I noticed that many people are looking for free PHP eBooks. So i decided to help them. No I will not write one but i will write where to find some good free PHP eBooks. Most common free PHP eBook is PHP manual. PHP manual you can download directly from PHP.net site in documentation section.

Another good PHP eBook is written by Poul Hudson you can read it online on his site http://www.hudzilla.org. I think this good is quite good for novices to PHP.

However you would never be a good PHP programmer after you reading a book. To became a real and good PHP programmer you must take a lot of practice. Any kind of PHP and MySQL tutorials is good way to learn.

Good luck learning PHP. If you have found a good free PHP eBook post a link in comments. Thanks.

More secure PHP image upload class tutorial

Friday, June 8th, 2007

In the internet are many php image upload tutorials, but most of them are not so secure. In this tutorial i try to teach you how to write not very complex but secure image upload class. First of all we should define class ant it variables:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class image_upload
{
	var $tmp_image;
	var $max_file_size = 100000;
	var $max_width = 800;
	var $max_height = 600;
	var $allow_types = array(
'image/jpeg', 
'image/png', 
'image/gif'
);
var $errors;
}
?>

For variables $max_file_size, $max_width, $max_height and $allow_types I assigned default values. There are two more variables its $errors for error printing and $tmp_image for $_FILES[’xxxx’] global variable.

Now then we have defined class and variables we can make some standard functions for image upload class. First we need to know if given file is really image so we use function exif_imagetype() witch reads firs file bytes and returns true if file is image else it returns false. (Note: exif_imagetype() function will work only if module exif is installed in server.)

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
function is_image ()
{
	if (exif_imagetype($this->tmp_image['tmp_name']))
	{
		$this->errors[] = 'Uploaded file is not image';
		return true;
	}
	else
	{
		return false;
	}
}

To check uploaded image type (mime type) i use next function. It searches for uploaded image type in $allow_types types array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function is_type ()
{
	if (in_array($this->tmp_image['type'], 
$this->allow_types))
	{
		return true;
	}
	else
	{
		$this->errors[] = 'Image type is 
not acceptable';
		return false;
	}
}

Next I check if image is suitable size:

1
2
3
4
5
6
7
8
9
10
11
12
function is_size ()
{
	if ($this->tmp_image['type'] <= $this->max_file_size)
	{
		return true;
	}
	else
	{
		$this->errors[] = 'Image file size is too big';
		return false;
	}
}

To check image dimensions I call getimagesize() function it returns array with image parameters.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function is_dimensions ()
{
	$size = getimagesize($this->tmp_image['tmp_name']);
	$width = $size[0];
	$height = $size[1];
	if ($width <= $this->max_width && 
$height <= $this->max_height)
	{
		return true;
	}
	else
	{
		$this->errors[] = 'Image is too height 
or too width';
		return false;
	}
}

Finally I wrote image upload function it has two parameters $dest – upload destination and $safe for safe image upload witch by default is false.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function upload_image ($dest, $safe=false)
{
	if ($safe)
	{
		$status = true;
 
		$status = $this->is_image();
		$status = $this->is_type();
		$status = $this->is_size();
		$status = $this->is_dimensions();
 
		return ($status)?move_uploaded_file(
$this->tmp_image['tmp_name'], $dest)
:false;
	}
	else
	{
		return move_uploaded_file(
$this->tmp_image['tmp_name'], $dest);
	}
}

Now class is ready for use. For class test I wrote a simle script.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
 
include('upload.class.php');
 
$IM = new image_upload();
 
if ($_FILES['photo'])
{
	$IM->tmp_image = $_FILES['photo'];
 
	if ($IM->upload_image($_SERVER['DOCUMENT_ROOT'].
'/tnimg/'.$IM->tmp_image['name'], true))
	{
		echo 'Image uploaded';
	}
	else
	{
		foreach ($IM->errors as $error)
		{
			echo $error.'<br />';
		}
	}
}
 
?>
<form method="post" enctype="multipart/form-data" action="">
	<label for="photo">Photo file</label>
	<input type="file" name="photo" />
	<input type="submit" name="submit" value="Upload" />
</form>