Jump to content

PHP Database Backup Class

Handy little tool I wrote

Page 1 of 1
  • You cannot start a new topic
  • This topic is locked

PHP Database Backup Class Handy little tool I wrote Rate Topic: -----

#1 User is offline   Randommark 

  • W.R. Private
  • Group: Members
  • Posts: 46
  • Joined: 05-February 08
  • Gender:Male
  • Location:Portsmouth, Englanshire

Post icon  Posted 21 May 2009 - 02:07 PM

A very long while ago I posted a query about this and couldn't find any easy solutions. So with a bit of spare time, I wrote the following class. I thought I'd share as it has proven to be handy for me.

<?php

/*
* Author: Mark Satterthwaite
* Date: 21 May 2009
* Email: mark.satterthwaite@gmail.com
*/

class dbbackup
{
	/* Database Connection Variables*/
	protected $DB_HOST = '';
	protected $DB_NAME = '';
	protected $DB_USER = '';
	protected $DB_PASS = '';
	
	/* Output variable used */
	protected $output = '';
	
	/* Create Connection */
	function setConnectionInfo($DB_HOST, $DB_NAME, $DB_USER, $DB_PASS)
	{
		$this->DB_HOST = $DB_HOST;
		$this->DB_NAME = $DB_NAME;
		$this->DB_USER = $DB_USER;
		$this->DB_PASS = $DB_PASS;
		
		$connection = mysql_pconnect($this->DB_HOST, $this->DB_USER, $this->DB_PASS) or trigger_error(mysql_error(),E_USER_ERROR);
		mysql_select_db($this->DB_NAME, $connection);
	}
	
	/* Do the backup, put the output to $output*/
	function backup()
	{
		// Get a list of tables
		$tables = $this->getTables();
		
		// Create SQL for each table
		foreach($tables as $table)
		{
			// Table Description
			$this->output .= $this->getTableDescription($table) . ";";
		
			$this->output .= "\n\n";
			
			// Table Contents
			$table_contents = $this->getTableContents($table);
			
			foreach($table_contents as $content)
			{
				$this->output .= "INSERT INTO `$table` (";
				
				$num_of_keys = sizeof(array_keys($content));
				$counter = 0;
				
				foreach(array_keys($content) as $key)
				{
					$this->output .= "`$key`";
					$counter++;
					
					if($counter != $num_of_keys)
						$this->output .= ",";
				}
				
				$this->output .= ") VALUES (";
				
				$counter = 0;
				foreach(array_keys($content) as $key)
				{
					$this->output .= "'".addslashes($content[$key])."'";
					$counter++;
					
					if($counter != $num_of_keys)
						$this->output .= ",";
				}
				$this->output .= ");\n";
			} 
			$this->output .= "\n";
		}
	}
	
	/* Returns the $output, incase you dont want a file to be written */
	function getOutput()
	{
		return $this->output;
	}
	
	/* Write the backup file. if no name is used, I will make one up for you*/
	function writeFile($sql_output = null)
	{
		
		if($sql_output == null){
			$sql_output = $this->DB_NAME."_".time().".sql";
		} if ($sql_output != null) {
			$sql_output = $sql_output;
		}
		
		$fh = fopen($sql_output, 'w+');
		fwrite($fh, $this->output);
		fclose($fh);
		
		return true;
	}
	
	/* Get a list of tables */
	protected function getTables()
	{
		$SQL = "SHOW TABLES FROM `$this->DB_NAME`;";
		$query = mysql_query( $SQL );
		
		$results = array();
		while($row = mysql_fetch_array( $query ))
			array_push($results, $row[0]);
		
		return $results;
	}
	
	/* Get the Description of a table */
	protected function getTableDescription($table){
		$SQL = "SHOW CREATE TABLE `$table`;";
		$query = mysql_query( $SQL );
		
		while($row = mysql_fetch_array( $query ))
			$results = $row[1];
		
		return $results;	
	}
	
	/* Get table contents */
	protected function getTableContents($table)
	{
		$SQL = "SELECT * FROM `$table`;";
		$query = mysql_query( $SQL );
		
		$results = array();

		while($row = mysql_fetch_assoc( $query )){
			$contents = array();
			$contents = $row;
			array_push($results, $contents);
		}
		
		return $results;	
	}
}
?>


And to use the script, something like this will work:

<?php
include 'dbbackup-class.php';

$dbbackup = new dbbackup();

$dbbackup->setConnectionInfo('host','dbname','user','password');

$dbbackup->backup();

$dbbackup->writeFile();
?>


If you want to specify a file name, just put a file name in the writeFile() function call as such:
$dbbackup->writeFile('backup.sql');

It should all be self explanitory, if not do not hesitate to ask.

Feel free to tinker and do with it what you want

This post has been edited by Randommark: 21 May 2009 - 02:23 PM

0

#2 User is offline   Ben Abrams 

  • The buddy system:never fails
  • Group: Administrators
  • Posts: 1,850
  • Joined: 04-April 06
  • Gender:Male

Posted 21 May 2009 - 05:27 PM

How does it handle large databases? Looks good though! =)

View PostSirkent, on 21 September 2007 - 04:26 AM, said:

<monty python high-pitched female voice>I DON'T LIKE SPAM!</monty python high-pitched female voice>
0

#3 User is offline   Randommark 

  • W.R. Private
  • Group: Members
  • Posts: 46
  • Joined: 05-February 08
  • Gender:Male
  • Location:Portsmouth, Englanshire

Posted 22 May 2009 - 02:47 AM

Honestly, I have no idea. I have used this class in several sites but admitingly, they are small/medium websites.

Just reading the code, I can see plenty of areas for improvement but I don't think it's too bad considering it was the frist class i've written.

I'll try some sort of stress test in a minute..... brb
0

#4 User is offline   Karl Buckland 

  • A.K.A. Sirkent
  • Group: Administrators
  • Posts: 2,145
  • Joined: 04-April 06
  • Gender:Male
  • Location:Kent, UK

Posted 22 May 2009 - 03:07 AM

Interesting! I'm curious why you wanted to replace Phpmyadmin or just mysqldump though? Was there a specific reason you wanted to overcome or are you simply interested in the programming challenge?
QUOTE(benbramz @ Aug 17 2007, 07:44 AM) Ive noticed that quite a few people are now adding quotes from the board into their signature. I think its started an new web-radiance craze.. :P
0

#5 User is offline   Randommark 

  • W.R. Private
  • Group: Members
  • Posts: 46
  • Joined: 05-February 08
  • Gender:Male
  • Location:Portsmouth, Englanshire

Posted 22 May 2009 - 03:11 AM

View PostSirkent, on May 22 2009, 08:07 AM, said:

Interesting! I'm curious why you wanted to replace Phpmyadmin or just mysqldump though? Was there a specific reason you wanted to overcome or are you simply interested in the programming challenge?


Always love a good challenge but I wanted some of my clients to be able to backup their database without the technical knowledge of how to use phpMyAdmin. They can then download the SQL file and save where ever they feel safe.

This all arised as one of my clients had used a host that lost all of their files and the database and had no real backup that we could use to restore it so I wrote this so it would limit the damage I suppose :)
0

#6 User is offline   Randommark 

  • W.R. Private
  • Group: Members
  • Posts: 46
  • Joined: 05-February 08
  • Gender:Male
  • Location:Portsmouth, Englanshire

Post icon  Posted 22 May 2009 - 05:02 AM

View Postbenbramz, on May 21 2009, 11:27 PM, said:

How does it handle large databases? Looks good though! =)


Right, I suppose what we all call large is different but this is what I just tested it on:

A database that has
- 248 tables
- 14603 records
- 17.8 MiB

I used this code to backup the database 100 times:

<?php
set_time_limit(0);
include 'dbbackup-class.php';

$averageTime = 0;

for($i = 0; $i < 100; $i++){

	$timeBegin = time();

	$dbbackup = new dbbackup();

	$dbbackup->setConnectionInfo('localhost','forums','root','');

	$dbbackup->backup();

	$dbbackup->writeFile("backup$i.sql");

	$timeEnd = time();

	$averageTime += ($timeEnd - $timeBegin);
	
	echo $i . " - " . ($timeEnd - $timeBegin) . "<br>";
}

echo "<br><h3>Average Time for 100 backups:" . ($averageTime/100) . " seconds</h3>";
?>


And got these results:

The number on the left is the backup number and the right number is how many seconds it took. Average was 13.19 seconds

Quote

0 - 19
1 - 25
2 - 20
3 - 15
4 - 29
5 - 25
6 - 19
7 - 15
8 - 10
9 - 25
10 - 25
11 - 20
12 - 20
13 - 10
14 - 10
15 - 11
16 - 21
17 - 9
18 - 20
19 - 24
20 - 9
21 - 19
22 - 9
23 - 10
24 - 10
25 - 25
26 - 9
27 - 10
28 - 25
29 - 19
30 - 9
31 - 10
32 - 10
33 - 19
34 - 10
35 - 9
36 - 10
37 - 9
38 - 15
39 - 20
40 - 9
41 - 9
42 - 10
43 - 10
44 - 10
45 - 19
46 - 10
47 - 9
48 - 10
49 - 10
50 - 14
51 - 14
52 - 15
53 - 10
54 - 9
55 - 9
56 - 10
57 - 9
58 - 10
59 - 9
60 - 10
61 - 9
62 - 19
63 - 10
64 - 9
65 - 10
66 - 19
67 - 10
68 - 9
69 - 10
70 - 20
71 - 9
72 - 10
73 - 9
74 - 10
75 - 10
76 - 9
77 - 10
78 - 9
79 - 9
80 - 11
81 - 10
82 - 9
83 - 14
84 - 15
85 - 19
86 - 29
87 - 10
88 - 14
89 - 10
90 - 19
91 - 9
92 - 10
93 - 9
94 - 10
95 - 10
96 - 9
97 - 10
98 - 10
99 - 9

Average Time for 100 backups:13.19 seconds

This post has been edited by Randommark: 22 May 2009 - 05:03 AM

0

#7 User is offline   Randommark 

  • W.R. Private
  • Group: Members
  • Posts: 46
  • Joined: 05-February 08
  • Gender:Male
  • Location:Portsmouth, Englanshire

Posted 22 May 2009 - 05:05 AM

One more thing, this was run on my local machine, if that make much of a difference.
0

#8 User is offline   Ben Abrams 

  • The buddy system:never fails
  • Group: Administrators
  • Posts: 1,850
  • Joined: 04-April 06
  • Gender:Male

Posted 24 May 2009 - 08:00 PM

Thats not too bad actually, for a script. Im assuming you had the script timeout disabled on your local machine though :P

View PostSirkent, on 21 September 2007 - 04:26 AM, said:

<monty python high-pitched female voice>I DON'T LIKE SPAM!</monty python high-pitched female voice>
0

#9 User is offline   Randommark 

  • W.R. Private
  • Group: Members
  • Posts: 46
  • Joined: 05-February 08
  • Gender:Male
  • Location:Portsmouth, Englanshire

Posted 25 May 2009 - 03:07 AM

View Postbenbramz, on May 25 2009, 01:00 AM, said:

Thats not too bad actually, for a script. Im assuming you had the script timeout disabled on your local machine though :P



Yup, hence why have "set_time_limit(0);" in the code sample. I dont need to set the a time limit when just doing one back, rather than 100 :)
0

#10 User is offline   sypher 

  • the owner3r
  • Group: Administrators
  • Posts: 1,578
  • Joined: 04-April 06
  • Location:North Wales, UK
  • Interests:Art, Boxing, MMA, Graphic Design, Web Design etc. ;)

Posted 25 May 2009 - 10:33 PM

Nice work, have you ever looked into the way oscommerce deals with a user mysql dump? Sounds dirty i know.

I may steal this from you in the future :D
sypher design - North Wales Web Design | Latest Work: - Scala Cinema

CSS - Can't See Sh*t
0

#11 User is offline   Randommark 

  • W.R. Private
  • Group: Members
  • Posts: 46
  • Joined: 05-February 08
  • Gender:Male
  • Location:Portsmouth, Englanshire

Posted 26 May 2009 - 03:03 AM

View Postsypher, on May 26 2009, 03:33 AM, said:

Nice work, have you ever looked into the way oscommerce deals with a user mysql dump? Sounds dirty i know.

I may steal this from you in the future :D


Dirty, just the way I like it. I havn't really ever used it or looked into it at depth, might have a gander later.

It's not stealing, I'm sharing with the world! :thumbup:
0

#12 User is offline   Rob Kaper 

  • W.R. Corporal
  • Group: Members
  • Posts: 97
  • Joined: 19-July 08
  • Gender:Male
  • Location:Rotterdam, NLD

Posted 22 October 2010 - 01:45 PM

Nice one!

But it also makes me happy to have full server access on a VPS. Full and direct access to mysqldump (or whatever equivalent for other databases) is a lot easier than even having to think about having to write and maintain such a script.

I actually do still wrap my backup script in PHP, all my site related system scripts are in PHP. That way they all have full access to all classes and methods relating to my site.
Rob Kaper - Rotterdam
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • This topic is locked

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users