Source for file iam_backup.php

Documentation is available at iam_backup.php


1 <?php
2 /**
3 * IAM_Backup A class for backing up an entire Database and send the dump to the browser or download it as a file
4 * @desc IAM_Backup A class for backing up an entire Database and send the dump to the browser or download it as a file.
5 * @package iam_backup
6 * @author Iván Ariel Melgrati <phpclasses@imelgrat.mailshell.com>
7 * @version 1.2
8 *
9 * Requires PHP v 4.0+ and MySQL 3.23+
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 */
21
22
23 /**
24 * IAM_Backup A class for backing up an entire Database and send the dump to the browser or download it as a file
25 * @package iam_backup
26 */
27 class iam_backup
28 {
29 /**
30 *
31 * @var string $host Host that holds the DB
32 * @access private
33 */
34 var $host="localhost";
35
36 /**
37 *
38 * @var string $dbname Database to back up
39 * @access private
40 */
41 var $dbname="mysql";
42
43 /**
44 *
45 * @var string $dbuser User to access the Database
46 * @access private
47 */
48 var $dbuser="root";
49
50 /**
51 *
52 * @var string $dbpass Password to access the Database
53 * @access private
54 */
55 var $dbpass="";
56
57 /**
58 *
59 * @var string $newline Newline character (OS dependant)
60 * @access private
61 */
62 var $newline;
63
64 /**
65 *
66 * @var Boolean $struct_only Indicates whether the backup will contain only the DB structure and no data (when true)
67 * @access private
68 */
69 var $struct_only = false;
70
71 /**
72 *
73 * @var string $output Whether to send the output to the browser (when false)or download it as a file (when true)
74 * @access private
75 */
76 var $output = true;
77
78 /**
79 *
80 * @var string $compress Indicates whether the dump will be compressed (using GZIP compression). It only has an effect when downloading the file.
81 * @access private
82 */
83 var $compress = true;
84
85 /**
86 *
87 * @var string $filename Indicates Path and name of the file (when the dump is done on the server). If not null, the dump will be performed on the local server. If null, the file will be sent to the browser.
88 * @access private
89 */
90 var $filename = "";
91
92 /**
93 * Initialize this class. Constructor
94 * @access public
95 * @param Mixed $host Host that holds the DB. The user of the class can pass it either a Hostaname (and fill in the rest of the data) or a Connection Object (and avoid filling in all the parameters). Thanks Sebastiaan van Stijn
96 * @param String $dbanme Database to back up
97 * @param String $dbuser User to access the Database
98 * @param String $dbpass Password to access the Database
99 * @param Boolean $output Whether to send the output to the browser (when false)or download it as a file (when true)
100 * @param Boolean $struct_only Indicates whether the backup will contain only the DB structure and no data (when true)
101 * @param Boolean $compress Indicates whether the dump will be compressed (using GZIP compression). It only has an effect when downloading the file.
102 * @param String $filename Indicates Path and name of the file (when the dump is done on the server)
103 */
104 function iam_backup($host = 'localhost', $dbname = 'mysql', $dbuser = 'root', $dbpass = '', $struct_only = false, $output = true, $compress = true, $filename="")
105 {
106 $this->output = $output;
107 $this->struct_only = $struct_only;
108 $this->compress = $compress;
109
110 /*
111 * check if 'host' contains a connection instead of a hostname
112 * Check takes place on two properties;
113 * 1) check if 'host' is an object
114 * 2) check if 'host' has a property called 'database' (any other connection-specific property should do)
115 */
116 if(is_object($host) && isset($host->database)){
117 $this->host = $host->host;
118 $this->dbname = $host->database;
119 $this->dbuser = $host->user;
120 $this->dbpass = $host->password;
121 }else{
122 $this->host = $host;
123 $this->dbname = $dbname;
124 $this->dbuser = $dbuser;
125 $this->dbpass = $dbpass;
126 }
127 $this->filename = $filename;
128 $this->newline = $this->_define_newline();
129 }
130
131 /**
132 * Generate the DB Dump.
133 * @access private
134 */
135 function _backup()
136 {
137 $now = gmdate('D, d M Y H:i:s') . ' GMT';
138
139 $newfile.= "#------------------------------------------".$this->newline;
140 $newfile.= "# Database Backup Class by Iván Melgrati".$this->newline;
141 $newfile.= "# Database: $this->dbname".$this->newline;
142 $newfile.= "# Date: $now".$this->newline;
143 $newfile.= "#------------------------------------------".$this->newline.$this->newline;
144
145 $result = mysql_pconnect("$this->host","$this->dbuser","$this->dbpass");
146 if(!$result) // If no connection can be obtained, return empty string
147 {
148 return "Error. Can´t connect to Database: $this->dbname";
149 }
150
151 if(!mysql_select_db("$this->dbname")) // If db can't be set, return empty string
152 {
153 return "Error. Database $this->dbname could not be selected.";
154 }
155
156 $result = @mysql_query("show tables from $this->dbname");
157 while (list($table) = @mysql_fetch_row($result))
158 {
159 $newfile .= $this->_get_def($table);
160 $newfile .= "$this->newline";
161 if(!$struct_only) // If table data also has to be written, get table contents
162 $newfile .= $this->_get_content($table);
163 $newfile .= "$this->newline";
164 $i++;
165 }
166
167 $this->_out($newfile);
168 }
169
170 /**
171 * Send the output to the browser
172 * @access private
173 * @param string $output Contains the database dump
174 */
175 function _out($dump)
176 {
177 if($this->filename)
178 {
179 $fptr= fopen($this->filename, "wb");
180 if ($fptr)
181 {
182 if($this->compress)
183 {
184 $gzbackupData = "\x1f\x8b\x08\x00\x00\x00\x00\x00".substr(gzcompress($dump,9),0,-4).pack('V',crc32($dump)).pack('V',strlen($dump));
185 fwrite($fptr, $gzbackupData);
186 }
187 else
188 fwrite($fptr, $dump);
189 fclose($fptr);
190 }
191 }
192 else
193 {
194 if(($this->compress) and ($this->output))
195 {
196 $gzbackupData = "\x1f\x8b\x08\x00\x00\x00\x00\x00".substr(gzcompress($dump,9),0,-4).pack('V',crc32($dump)).pack('V',strlen($dump));
197 echo $gzbackupData;
198 }
199 else
200 echo $dump;
201 }
202 }
203
204 /**
205 * Generate the selected table's definition
206 * @access private
207 * @return String table definition dump
208 * @param String $tablename Name of the table to back up
209 */
210 function _get_def($tablename)
211 {
212 $def = "";
213 $def .="#------------------------------------------".$this->newline;
214 $def .="# Table definition for $tablename".$this->newline;
215 $def .="#------------------------------------------".$this->newline;
216 $def .= "DROP TABLE IF EXISTS $tablename;".$this->newline.$this->newline;
217 $def .= "CREATE TABLE $tablename (".$this->newline;
218 $result = @mysql_query("SHOW FIELDS FROM $tablename") or die("Table $tablename not existing in database");
219 while($row = @mysql_fetch_array($result))
220 {
221 $def .= " $row[Field] $row[Type]";
222 if ($row["Default"] != "") $def .= " DEFAULT '$row[Default]'";
223 if ($row["Null"] != "YES") $def .= " NOT NULL";
224 if ($row[Extra] != "") $def .= " $row[Extra]";
225 $def .= ",$this->newline";
226 }
227 $def = ereg_replace(",$this->newline$","", $def);
228
229 $result = @mysql_query("SHOW KEYS FROM $tablename");
230 while($row = @mysql_fetch_array($result))
231 {
232 $kname=$row[Key_name];
233 if(($kname != "PRIMARY") && ($row[Non_unique] == 0)) $kname="UNIQUE|$kname";
234 if(!isset($index[$kname])) $index[$kname] = array();
235 $index[$kname][] = $row[Column_name];
236 }
237
238 while(list($x, $columns) = @each($index))
239 {
240 $def .= ",$this->newline";
241 if($x == "PRIMARY") $def .= " PRIMARY KEY (" . implode($columns, ", ") . ")";
242 else if (substr($x,0,6) == "UNIQUE") $def .= " UNIQUE ".substr($x,7)." (" . implode($columns, ", ") . ")";
243 else $def .= " KEY $x (" . implode($columns, ", ") . ")";
244 }
245 $def .= "$this->newline);";
246
247 return (stripslashes($def));
248 }
249
250 /**
251 * Generate the selected table's contents
252 * @access private
253 * @return String table data as INSERT statements
254 * @param String $tablename Name of the table to back up
255 */
256 function _get_content($tablename)
257 {
258 $content = "";
259
260 $result = @mysql_query("SELECT * FROM $tablename");
261
262 if(@mysql_num_rows($result)>0)
263 {
264 $content .="#------------------------------------------".$this->newline;
265 $content .="# Data inserts for $tablename".$this->newline;
266 $content .="#------------------------------------------".$this->newline;
267 }
268
269 while($row = @mysql_fetch_row($result))
270 {
271 $insert = "INSERT INTO $tablename VALUES (";
272
273 for($j=0; $j<@mysql_num_fields($result);$j++)
274 {
275 if(!isset($row[$j])) $insert .= "NULL,";
276 else if($row[$j] != "") $insert .= "'".addslashes($row[$j])."',";
277 else $insert .= "'',";
278 }
279
280 $insert = ereg_replace(",$", "", $insert);
281 $insert .= ");$this->newline";
282 $content .= $insert;
283 }
284
285 return $content.$this->newline;
286 }
287
288 /**
289 * Define EOL character according to target OS
290 * @return String a string containing the newline sequence used by the client (browser)
291 * @access private
292 */
293 function _define_newline()
294 {
295 $unewline = "\r\n";
296
297 if (strstr(strtolower($_SERVER["HTTP_USER_AGENT"]), 'win'))
298 {
299 $unewline = "\r\n";
300 }
301 else if (strstr(strtolower($_SERVER["HTTP_USER_AGENT"]), 'mac'))
302 {
303 $unewline = "\r";
304 }
305 else
306 {
307 $unewline = "\n";
308 }
309
310 return $unewline;
311 }
312
313 /**
314 * Define the client's browser type
315 * @return String a String containing the browser type (IE, OPERA, MOZILA, etc.)
316 * @access private
317 */
318 function _get_browser_type()
319 {
320 $USER_BROWSER_AGENT="";
321
322 if (ereg('OPERA(/| )([0-9].[0-9]{1,2})', strtoupper($_SERVER["HTTP_USER_AGENT"]), $log_version))
323 {
324 $USER_BROWSER_AGENT='OPERA';
325 }
326 else if (ereg('MSIE ([0-9].[0-9]{1,2})',strtoupper($_SERVER["HTTP_USER_AGENT"]), $log_version))
327 {
328 $USER_BROWSER_AGENT='IE';
329 }
330 else if (ereg('OMNIWEB/([0-9].[0-9]{1,2})', strtoupper($_SERVER["HTTP_USER_AGENT"]), $log_version))
331 {
332 $USER_BROWSER_AGENT='OMNIWEB';
333 }
334 else if (ereg('MOZILLA/([0-9].[0-9]{1,2})', strtoupper($_SERVER["HTTP_USER_AGENT"]), $log_version))
335 {
336 $USER_BROWSER_AGENT='MOZILLA';
337 }
338 else if (ereg('KONQUEROR/([0-9].[0-9]{1,2})', strtoupper($_SERVER["HTTP_USER_AGENT"]), $log_version))
339 {
340 $USER_BROWSER_AGENT='KONQUEROR';
341 }
342 else
343 {
344 $USER_BROWSER_AGENT='OTHER';
345 }
346
347 return $USER_BROWSER_AGENT;
348 }
349
350 /**
351 * Define MIME-TYPE according to target Browser
352 * @return String a string containing the MIME-TYPE header to send to the browser
353 * @access private
354 */
355 function _get_mime_type()
356 {
357 $USER_BROWSER_AGENT= $this->_get_browser_type();
358
359 $mime_type = ($USER_BROWSER_AGENT == 'IE' || $USER_BROWSER_AGENT == 'OPERA')
360 ? 'application/octetstream'
361 : 'application/octet-stream';
362 return $mime_type;
363 }
364
365 /**
366 * Generate the DB backup and send it to browser or download it as a file
367 * @access public
368 */
369 function perform_backup()
370 {
371
372 $now = gmdate('D, d M Y H:i:s') . ' GMT';
373 if ($this->compress)
374 {
375 $filename = $this->dbname.".sql";
376 $ext = "gz";
377 }
378 else
379 {
380 $filename = $this->dbname;
381 $ext = "sql";
382 }
383
384 $USER_BROWSER_AGENT= $this->_get_browser_type();
385
386 if($this->filename)
387 {
388 $this->_backup();
389 }
390 else
391 if ($this->output == true)
392 {
393 header('Content-Type: ' . $this->_get_mime_type());
394 header('Expires: ' . $now);
395 if ($USER_BROWSER_AGENT == 'IE')
396 {
397 header('Content-Disposition: inline; filename="' . $filename . '.' . $ext . '"');
398 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
399 header('Pragma: public');
400 }
401 else
402 {
403 header('Content-Disposition: attachment; filename="' . $filename . '.' . $ext . '"');
404 header('Pragma: no-cache');
405 }
406
407 $this->_backup();
408 }
409 else
410 {
411 echo "<html><body><pre>";
412 echo htmlspecialchars($this->_backup());
413 echo "</PRE></BODY></HTML>";
414 }
415 }
416 }
417
418 ?>

Documentation generated on Tue, 16 Dec 2003 20:31:34 -0300 by phpDocumentor 1.2.3