kreoton web development

More secure PHP image upload class tutorial

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>

Digg.com style pagination function

June 5th, 2007

I introduce nice Digg.com style pagination function. This pagination function is very flexible and easy to implement in all kind of scripts. All you have to do is to set current page parameter, total pages parameter and pagination format. I will give you an example:

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
<?
//include paginate funtion
include('paginate.php');
 
//get total pages number
$total = $db['result']['total_pages'];
 
//get curent page
$page = $_GET['p'];
 
//formate pagination layout
 
$format_pg = array (
	'start_tag'	=> '<ul>',
	'close_tag'	=> '</ul>',
	'a_open'	=> '<li>',
	'a_close'	=> '</li>',
	'a_curent'	=> ' style="color:red"',
	'url_q'		=> '?p=%d',
	'lang_next'	=> 'NEXT',
	'lang_previous'	=> 'PREVIOUS',
	'a_space'	=> '...',					
	);
 
//finaly print pagination
 
echo paginate($page, $total, $format_pg);
 
?>

Paginate function is free. To download paginate function hit following link:

Download paginate Rate it On HotScripts.com

RunFast - good way to lounch programs

June 5th, 2007

If you want to keep your desktop and quick launch clean you should have this program. It supports aliases, which allows you to create custom commands and it also supports execution of multiple commands at one time. All you need to do is just hit Ctrl+R type in alias of program (in example: firefox) and hit enter and your program is open.

You can download RunFast from here.

Smarty included file caching

May 30th, 2007

Smarty is very good templating system for every PHP application. Once I coded one application using Smarty and Apache mod rewrite. I had one template file i witch i included other template files. After some time my project had very high traffic so i needed to on cache. You probably know that Smarty does not have cache future for included file, so i googled for some time and found some useful smarty hack. I added this hack to smarty core files and wow it worked, all i had to do is just add variable to template file inclusion in example:

1
{include file='includedfile.tpl' __cache__=120}

Where __cache__ shows that i start cache for 120 second everything worked fine until i browsed to other pages. Main bug of this hack is you can not use paging on your application. To solve this problem i edited smary code and added __id__ variable to Smarty included template files. It works very simple in example:

index.php file:

1
2
3
4
5
6
7
<?php
if ($_GET['page']) {
$smarty->assign('page', $_GET['page']);
//getting dynamic content
}
$smarty->display('main.tpl');
?>

main.tpl

1
2
3
4
5
6
7
8
<html>
<head>
<title>{$pagetitle}</title>
</head>
<body>
{include file='dynamiccontent.tpl' __cache__=3600 __id__=$page}
</body>
</html>

Variable __id__ assigns in witch dynamic content page I am.

You can download hacked version of Smarty by clicking of following link http://kreoton.net/downloads/samrty.rar