OOP PHP Progress Bar For Any Purpose

Many ways to create a progress bar but in this blog post I give example on PHP Progress bar built with OOP.
The reason I use OOP is that the class can be used again for any purpose which need progress bar.

We need interface OOP object which contains three methods which are get_max() returns maximum value that progress bar will have,
get_progress() returns current progress value or progress percentage. This progress percentage value sets progress bar value and do_work() to do a real work like database or files operation or else.

I use JQuery to draw Progress Bar in User Interface because of simplicity to make it with JQuery. I assume that you already know basic of progress bar and JQuery.

OOP Design

I use interface OOP object as a design and contract of class so that each class which implements that interface must have all methods declared in interface.
Interface iProgressBar.php:

interface iProgressBar {
	function get_max();
	function get_progress();
	function do_work();
}

Interface’s methods does not have body only declaration of functions.

Class file which implements that interface should include iProgresssBar.php

include_once "iProgressBar.php";

class DBProgressBar implements iProgressBar {
	
	function __construct() { 
		
	}
	
	function get_max() {
		
	}
	
	function get_progress() {
		
	}
	
	function do_work() {
	
	}
}

To implement an interface we must use ‘implements’ keyword followed by interface’s name at class declaration and also include all interface’s methods inside class.

JQuery Progress Bar

Here’s an example on basic JQuery Progress Bar:

<html>
<head>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
<script src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js'></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/ui-lightness/jquery-ui.css" type="text/css" media="all" />

<script type="text/javascript">
var total=0;
	$(document).ready(function() {
		total = Math.floor(40+ Math.random()*40);
		var current = 0;
		window.setTimeout("progress()",0);		
	});
	
	function progress() {
		
		if (typeof current=="undefined") {
			current = 0;
			$("#progbar").progressbar({
				value: 0
			});
		}
		
		if (current <= total) {
			current = current + 1;
			
			$("#progbar").progressbar({
				value: Math.floor(current*100/total)
			});
			window.setTimeout("progress()",1000);
		}
	}
	
	
</script>

</head>
<body>
<div id="progbar"></div>
</body>
</html>

Save above code as HTML file and run it. If nothing wrongs then you will see a progress bar moving from zero to its max value.
JQuery Javascript and CSS is taken from ajax.googleapis.com so in order to test it we need internet connection. We can download the .js and css file at JQuery related websites and embed it on script.

Database Progress Bar Example

In this example, the code will copy SQLServer records from HumanResource.Employee table from AdventureWorks Database to TestDB.
DBProgressBar.php:

include_once "iProgressBar.php";

class DBProgressBar implements iProgressBar {
	private $host, $user, $pwd;
	function __construct() { 
		$this->host = ".\SQLEXPRESS";
		$this->user = "sa";
		$this->pwd = "";
	}
	
	function get_max() {
		$AWconn = mssql_connect($this->host,$this->user,$this->pwd, true);
		mssql_select_db("AdventureWorks", $AWconn);
		$sql = "select count(*) from HumanResources.Employee";
		$query_stmt = mssql_query($sql, $AWconn);
		$row = mssql_fetch_array($query_stmt, MSSQL_NUM);
		mssql_close($AWconn);
		
		return $row[0];
	}
	
	function get_progress() {
		$TDconn = mssql_connect($this->host,$this->user,$this->pwd);
		mssql_select_db("TestDB", $TDconn);
		$sql = "select count(*) from Employee";
		$query_stmt = mssql_query($sql, $TDconn);
		$row = mssql_fetch_array($query_stmt, MSSQL_NUM);
		mssql_close($TDconn);
		
		return $row[0];
	}
	
	function do_work() {
		$AWconn = mssql_connect($this->host,$this->user,$this->pwd, true);
		mssql_select_db("AdventureWorks", $AWconn);
		
		$TDconn = mssql_connect($this->host,$this->user,$this->pwd, true);
		mssql_select_db("TestDB", $TDconn);
		mssql_query("delete from Employee", $TDconn);
		
		$sql = "select NationalIDNumber, ContactID, LoginID, Title from HumanResources.Employee";
		$query_stmt = mssql_query($sql, $AWconn);
		while ($row = mssql_fetch_array($query_stmt, MSSQL_NUM)) {
			$sql = "insert into Employee (NationalIDNumber, ContactID, LoginID, Title) 
				values ('".$row[0]."',".$row[1].",'".$row[2]."','".$row[3]."')";
			
			mssql_query($sql, $TDconn);
			usleep(50000);
		}
		mssql_close($AWconn);
		mssql_close($TDconn);
	}
}

And here is implementation of DBProgressBar class and JQuery (copytable.php and db_progbar.php):
copytable.php:

include_once "DBProgressBar.php";
$dbprg = new DBProgressBar();
switch ($_GET["work"]) {
	case "max":
		echo $dbprg->get_max();
		break;
	case "do":
		$dbprg->do_work();
		break;
	case "progress":
		echo $dbprg->get_progress();
		break;
}

Above code is like controller to decide which function will execute based on $_GET["work"] querystring.

db_progbar.php:

<html>
<head>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
<script src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js'></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/ui-lightness/jquery-ui.css" type="text/css" media="all" />
<script type="text/javascript">
	var progress;
	var maxvalue;
	var func_id;
	$(document).ready(function() {
	});
	
	function do_work() {
		$.ajax({
			url: "copytable.php",
			type: "GET",
			data: "work=do"
			
		});		
	}
	
	function copytable() {
		$.ajax({
			async: false,
			url: "copytable.php",
			type: "GET",
			data: "work=max",
			success: function(response) {
				maxvalue = response;				
			}
		});
				
		do_work();
		progress=0;
		update_progress();
	}
	
	function update_progress() {		
		if (parseInt(progress) < parseInt(maxvalue)) {
			if (progress==0) {
				$("#progbar").progressbar({
					value: 0
				});
			}
			$.ajax({
				url: "copytable.php",
				type: "GET",
				data: "work=progress",
				success: function(response) {
					
					progress = response;
					$("#progbar").progressbar({
						value: Math.floor(progress*100/maxvalue)
					});
					
					if (parseInt(progress) < parseInt(maxvalue)) {
						func_id = setTimeout("update_progress()", 100);
					} else {
						alert("Done");
					}
					
				}
			});
			
		}
	}
</script>
</head>
<body>
<input type=button id="btncopy" value="Copy Table" onclick="copytable()" />
<div id="progbar"></div>
</body>
</html>

copytable() calls an Url (copytable.php) with parameter work=max to get maximum record number and then after that execute do_work() and update_progress functions to process copy table and get progress or copied record count with related parmeters
All function uses Ajax to process asynchronously and its response text sets to progress bar value.

File Upload Progress Bar Example

FilProgressBar class file:

include_once "iProgressBar.php";

class FileProgressBar implements iProgressBar {
	private $upload_dir;
	function __construct() { 
		$this->upload_dir = "uploads";
		
	}
	
	function get_max($filepath=null) {
		return filesize($filepath);
	}
	
	function get_progress() {
		$tmpfolder = ini_get("upload_tmp_dir");
		if ($handle = opendir($tmpfolder)) {
			while (false !== ($entry = readdir($handle))) {
				if (is_file($tmpfolder."\\".$entry)) {
					return filesize($tmpfolder."\\".$entry);					
				}
			}
		}
		
		if (file_exists($this->upload_dir."/" .$filename)) {
			return filesize($this->upload_dir."/".$filename);
		}
		return "";
	}
	
	function do_work($idxfile=null) {
		$filename = $_FILES[$idxfile]["name"];		
		move_uploaded_file($_FILES[$idxfile]["tmp_name"], $this->upload_dir."/" .$filename);
		echo "done";
	}
}

It is better to do file upload by patching php with apc, perl, pecl etc but in this post I only give simple example.

File_upload.php as controller:

include_once "FileProgressBar.php";
$fb = new FileProgressBar();

switch ($_GET["work"]) {
	case "do":
		$fb->do_work("file1");
		break;
	
	case "max":	
		echo $fb->get_max($_GET["filepath"]);
		
		break;
	case "progress":
		echo $fb->get_progress();
		break;
}

Implementation file to do file upload with progressbar:

<html>
<head>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
<script src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js'></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/ui-lightness/jquery-ui.css" type="text/css" media="all" />
<script language="javascript">
	var maxvalue;
	var progress;
$(document).ready(function() {
	$("#btnsubmit").click(function() {
		
		$.ajax({
			async: false,
			url: "file_upload.php",
			type: "GET",
			data: "work=max&filepath=" + $("#file1").val(),
			success: function(response) {				
				maxvalue=response;
			}
		});
		do_work();
		progress=0;
		update_progress();
		
	});
});

function do_work() {
	$("#form1").submit();
}

function update_progress() {		
	if (parseInt(progress) < parseInt(maxvalue)) {
		if (progress==0) {
			$("#progbar").progressbar({
				value: 0
			});
		}
		$.ajax({
			url: "file_upload.php",
			type: "GET",
			data: "work=progress",
			success: function(response) {
				if (response=="")
					progress = 0;
				else
					progress = response;
				$("#progbar").progressbar({
					value: Math.floor(progress*100/maxvalue)
				});
				
				if (parseInt(progress) < parseInt(maxvalue)) {
					func_id = setTimeout("update_progress()", 100);
				} else {
					alert("Done");
				}
				
			}
		});		
	}
}
</script>
</head>
<body>
<form id='form1' method='post' enctype="multipart/form-data" target="ifrm" action="file_upload.php?work=do">
<input type="file" id="file1" name="file1" /><br />
<input type="button" name="btnsubmit" value="Upload File" id="btnsubmit" />
<div id="progbar"></div>
</form>

</body>
</html>

Summary

Any process using OOP progress bar in this post will have three methods: get_max(), get_progress(), do_work(). Classes must implement an interface so that their methods will bound to interface’s method declaration.

Any javascript method may be used to create User Interface Progress Bar. JQuery make it simple

Advertisements

3 responses to “OOP PHP Progress Bar For Any Purpose

  1. Please i need help to implement Progress bar with above mentioned php scripts. Some one please help me

  2. Hello

    In the JQuery Progress Bar implementation there is a mistake.
    Definition of variable total should be moved outside the function that is excuted on the ready document event. Otherwise total is undefined
    inside the progress function and the second if is never executed
    resulting in a statis progress bar.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s