Avatar billede angelenglen Nybegynder
21. februar 2003 - 00:44 Der er 9 kommentarer og
1 løsning

Mysql backup-script

-i phpmyadmin er der en funktion til at lave et "dump" af ens database

jeg vil gerne have på min side sådan at man kan klikke på et link, og så åbner den en ny side, med et "dump" af et par af databaserne i.
-eller endnu bedere: at den gemmer filen på harddisken - ligesom fx phpBB kan gøre det.

(hvis den kan gemme filen på harddisken, ville det være rart hvis filnavnet automatisk blev kombineret med datoen - fx "backup28-02-03.sql")

-jeg behøber ikke en funktion til at genskabe backup'en ind i databasen igen, det kan jeg bruge phpmyadmin til.
Avatar billede avminarm Juniormester
21. februar 2003 - 08:59 #1
her er et script, som gemmer Db i en fil:
<?php
   
  $dbhost = "**********";
  $dbuname = "*********";
  $dbpass = "*******";
  $dbname = "********";

  @set_time_limit(600);
  $crlf="\n";

  // Danish Text   
  $strNoTablesFound = "Ingen databasetabeller fundet";
  $strHost = "Host";
  $strDatabase = "Database ";
  $strTableStructure = "Struktur for tabel";
  $strDumpingData = "Indhold af tabel";
  $strError = "Fejl";
  $strSQLQuery = "SQL-query";
  $strMySQLSaid = "MySQL: ";
  $strBack = "Tilbage";
  $strFileName = "DB-dump";
  $strName = "Backup af database";
  $strDone = "Downloadet d.";
  $strat = "kl.";
  $date_jour = date ("d-m-Y");       
       
  header("Content-disposition: filename=$strFileName $dbname $date_jour.sql");
  header("Content-type: application/ms-download");
  header("Pragma: no-cache");
  header("Expires: 0");
       
  // doing some DOS-CRLF magic...
  $client = getenv("HTTP_USER_AGENT");
  if(ereg('[^(]*\((.*)\)[^)]*',$client,$regs))
  {
    $os = $regs[1];
    // this looks better under WinX
    if (eregi("Win",$os))
      $crlf="\r\n";
  }
       
       
  function my_handler($sql_insert)
  {
    global $crlf;
    echo "$sql_insert;$crlf";
  }
       
  // Get the content of $table as a series of INSERT statements.
  // After every row, a custom callback function $handler gets called.
  // $handler must accept one parameter ($sql_insert);
  function get_table_content($db, $table, $handler)
  {
    $result = mysql_db_query($db, "SELECT * FROM $table") or mysql_die();
    $i = 0;
    while($row = mysql_fetch_row($result))
    {
      $table_list = "(";
       
      for($j=0; $j<mysql_num_fields($result);$j++)
                    $table_list .= mysql_field_name($result,$j).", ";
       
      $table_list = substr($table_list,0,-2);
      $table_list .= ")";
       
      if(isset($GLOBALS["showcolumns"]))
        $schema_insert = "INSERT INTO $table $table_list VALUES (";
      else
        $schema_insert = "INSERT INTO $table VALUES (";
       
      for($j=0; $j<mysql_num_fields($result);$j++)
      {
        if(!isset($row[$j]))
          $schema_insert .= " NULL,";
        elseif($row[$j] != "")
          $schema_insert .= " '".addslashes($row[$j])."',";
        else
          $schema_insert .= " '',";
      }
      $schema_insert = ereg_replace(",$", "", $schema_insert);
      $schema_insert .= ")";
      $handler(trim($schema_insert));
      $i++;
    }
    return (true);
  }
       
  // Return $table's CREATE definition
  // Returns a string containing the CREATE statement on success
  function get_table_def($db, $table, $crlf)
  {
    $schema_create = "";
    $schema_create .= "DROP TABLE IF EXISTS $table; CREATE TABLE $table ($crlf";
       
    $result = mysql_db_query($db, "SHOW FIELDS FROM $table") or mysql_die();
    while($row = mysql_fetch_array($result))
    {
      $schema_create .= "  $row[Field] $row[Type]";
       
      if(isset($row["Default"]) && (!empty($row["Default"]) || $row["Default"] == "0"))
        $schema_create .= " DEFAULT '$row[Default]'";
      if($row["Null"] != "YES")
        $schema_create .= " NOT NULL";
      if($row["Extra"] != "")
        $schema_create .= " $row[Extra]";
      $schema_create .= ",$crlf";
    }
    $schema_create = ereg_replace(",".$crlf."$", "", $schema_create);
    $result = mysql_db_query($db, "SHOW KEYS FROM $table") or mysql_die();
    while($row = mysql_fetch_array($result))
    {
      $kname=$row['Key_name'];
      if(($kname != "PRIMARY") && ($row['Non_unique'] == 0))
        $kname="UNIQUE|$kname";
      if(!isset($index[$kname]))
        $index[$kname] = array();
      $index[$kname][] = $row['Column_name'];
    }
       
    while(list($x, $columns) = @each($index))
    {
      $schema_create .= ",$crlf";
      if($x == "PRIMARY")
        $schema_create .= "  PRIMARY KEY (" . implode($columns, ", ") . ")";
      elseif (substr($x,0,6) == "UNIQUE")
        $schema_create .= "  UNIQUE ".substr($x,7)." (" . implode($columns, ", ") . ")";
      else
        $schema_create .= "  KEY $x (" . implode($columns, ", ") . ")";
    }
       
    $schema_create .= "$crlf)";
    return (stripslashes($schema_create));
  }
       
  function mysql_die($error = "")
  {
    echo "<b> $strError </b><p>";
    if(isset($sql_query) && !empty($sql_query))
    {
      echo "$strSQLQuery: <pre>$sql_query</pre><p>";
    }
    if(empty($error))
      echo $strMySQLSaid.mysql_error();
    else
      echo $strMySQLSaid.$error;
    echo "<br><a href=\"java script:history.go(-1)\">$strBack</a>";
    exit;
  }
       
  global $bruger, $dbhost, $dbuname, $dbpass, $dbname;
  mysql_connect($dbhost, $dbuname, $dbpass);
  @mysql_select_db("$dbname") or die ("Kunne ikke forbinde til databasen");
       
  $tables = mysql_list_tables($dbname);
       
  $num_tables = @mysql_numrows($tables);
  if($num_tables == 0)
  {
    echo $strNoTablesFound;
  }
  else
  {
    $i = 0;
    $heure_jour = date ("H:i");
    print "# ========================================================$crlf";
    print "#$crlf";
    print "# $strName : $dbname$crlf";
    print "# $strDone $date_jour $strat $heure_jour $crlf";
    print "#$crlf";
    print "# ========================================================$crlf";
    print "$crlf";
           
    while($i < $num_tables)
    {
      $table = mysql_tablename($tables, $i);
       
      print $crlf;
      print "# --------------------------------------------------------$crlf";
      print "#$crlf";
      print "# $strTableStructure '$table'$crlf";
      print "#$crlf";
      print $crlf;
       
      echo get_table_def($dbname, $table, $crlf).";$crlf$crlf";
               
      print "#$crlf";
      print "# $strDumpingData '$table'$crlf";
      print "#$crlf";
      print $crlf;
           
      get_table_content($dbname, $table, "my_handler");
       
      $i++;
    }
  }
       
?>
Avatar billede angelenglen Nybegynder
21. februar 2003 - 12:42 #2
nu har jeg ikke testet den, men er der mulighed for at hardcode ind i den hvadfor tabeller i databasen den skal tage med?
Avatar billede avminarm Juniormester
21. februar 2003 - 13:35 #3
jeg er ikke helt sikker - har ikke prøvet det, men i linien:

  $tables = mysql_list_tables($dbname);

Tror jeg du kan rette selv
Avatar billede angelenglen Nybegynder
21. februar 2003 - 18:14 #4
wooo den virker!

hvis jeg nu fx vil have backup af følgende tabeller, hvad erstatter jeg så:
$tables = mysql_list_tables($dbname); med?
følgende tabeller:
domain_cars
domain_news
domain_pics
domain_stat
domain_users
Avatar billede angelenglen Nybegynder
21. februar 2003 - 18:14 #5
-for jeg går ud fra det skal være et array, og jeg aner ikke noget om hvordan jeg lavet er array..
Avatar billede tefcke Nybegynder
21. februar 2003 - 22:10 #6
Jeg har også lånt koden fra php-myadmin. Du skal bare ændre variablen $DB_NAME til navnet på databasen som skal dumpes, samt variablen $DB_BACKUP_DIR til hvor hvor filen skal gemmes:

-- filen: config.inc : indholder alle mulige config vars --
/* MySQL Settings */
$DB_HOST    = "...";
$DB_USER    = "...";
$DB_PASSWORD = "...";
$DB_NAME    = "...";
/* MySQL Backup settings */
$DB_BACKUP_DIR      = "mysql/backup";
$DB_BACKUP          = TRUE; // auto backup database! NB: May consume alot of diskspace
$DB_BACKUP_CLEANUP  = TRUE; // auto cleanup so there only will be $DB_BACKUP_MAXFILES files at the most!
$DB_BACKUP_MAXFILES = 50; // 0 = unlimited



-- filen: libary.inc : som er min fil med alle mulige brugbare funktioner :) --
/*
* Function to make a database dump to file
* (kan ændres til at tage 1 indgående parameter,
* som er navnet på databasen der skal dumpes.
*/
function db_dump()
{
  global $DB_NAME, $DB_BACKUP_DIR, $DB_BACKUP;
  if ($DB_BACKUP) {
    // Write to file
    $filename = date("Y.m.d.H.i.s").".sql";
    /* Do the header */
    $today = date("l jS \o\f F, H:i:s (@B)");
    $white_space = str_repeat(" ", (54 - strlen($today)));
    $content = "";
    $content .= "#############################################################\n";
    $content .= "#                                                          #\n";
    $content .= "#    THIS FILE WAS AUTOMATICALLY GENERATED ON:            #\n";
    $content .= "#    ".$today.$white_space."#\n";
    $content .= "#                                                          #\n";
    $content .= "#    DENNE FIL INDEHOLDER ET DATABASE DUMP FRA            #\n";
    $content .= "#    DATABASEN Movie_DB.                                  #\n";
    $content .= "#                                                          #\n";
    $content .= "#    POWERED BY - PHP & MYSQL                              #\n";
    $content .= "#                                                          #\n";
    $content .= "#    © RASMUS PEDERSEN (math.rasmus@post.cybercity.dk)    #\n";
    $content .= "#                                                          #\n";
    $content .= "#############################################################\n";

    $result = mysql_list_tables($DB_NAME);
    while ($table = mysql_fetch_row($result)) {
      // Get table fields and properties
      $table_info = MySQLGetQuery("
        SHOW FIELDS FROM ".$table[0]);
      foreach ($table_info as $row) {
        // Create a printable string
        $row_array[] = $row['Field']." ".strtoupper($row['Type']).($row['Null']=="" ? " NOT NULL" : "");
        $table_fields[] = $row['Field'];
        // Catch the primary key(s)
        if (strtolower($row['Key'])=="pri") {
          $row_key[] = $row['Field'];
        }
      }
      // Get the table type
      $table_type = MySQLGetQuery("
        SHOW TABLE STATUS LIKE '".$table[0]."'");

      /*
      * Get table data
      */
      $table_data = mysql_query("
        SELECT *
        FROM ".$table[0]);
      // Format table data

      /*
      * The following piece of code is has been customiced for
      * my needs. It's made by staybyte, and orginates from
      * the project phpMyAdmin (http://www.phpMyAdmin.net)
      */
      if ($table_data != FALSE) {
        $fields_cnt = mysql_num_fields($table_data);
        $rows_cnt  = mysql_num_rows($table_data);
        // Checks whether the field is an integer or not
        for ($j = 0; $j < $fields_cnt; $j++) {
          $field_set[$j] = mysql_field_name($table_data, $j);
          $type          = mysql_field_type($table_data, $j);
          if ($type == "tinyint" || $type == "smallint" || $type == "mediumint" || $type == "int" || $type == "bigint"  ||$type == "timestamp") {
            $field_num[$j] = TRUE;
          } else {
            $field_num[$j] = FALSE;
          }
        } // end for
        $search      = array("\x00", "\x0a", "\x0d", "\x1a"); //\x08\\x09, not required
        $replace      = array("\0", "\n", "\r", "\Z");
        $current_row  = 0;
        @set_time_limit($GLOBALS['cfgExecTimeLimit']);
        while ($row = mysql_fetch_row($table_data)) {
          $current_row++;
          for ($j = 0; $j < $fields_cnt; $j++) {
            if (!isset($row[$j])) {
              $values[] = "NULL";
            } else if ($row[$j] == "0" || $row[$j] != "") {
              // a number
              if ($field_num[$j]) {
                $values[] = $row[$j];
              }
              // a string
              else {
                $values[] = "'" . str_replace($search, $replace, sql_add_slashes($row[$j])) . "'";
              }
            } else {
              $values[]    = "''";
            } // end if
          } // end for
          // Extended inserts case
          $insert_line[] = "(".implode(", ", $values).")";
          unset($values);
        } // end while
      } // end if ($result != FALSE)

      /* Append table definitions and data dump */
    $content .= "\n\n-- Struktur dump for tabellen "
            .  $table[0]
            .  "\nDROP TABLE IF EXISTS "
            .  $table[0]
            .  ";\nCREATE TABLE "
            .  $table[0]
            .  " (\n  "
            .  implode(",\n  ", $row_array)
            .  ",\n  PRIMARY KEY ("
            .  implode(", ", $row_key)
            .  ")\n) TYPE="
            .  $table_type[0]['Type']
            .  ";\n\n-- Data dump for tabllen "
            .  $table[0]
            .  "\nINSERT INTO "
            .  $table[0]
            .  " ("
            .  implode(", ", $table_fields)
            .  ")\nVALUES\n"
            .  implode(",\n", $insert_line)
            .  ";\n";
      unset($row_array, $row_key, $table_fields, $insert_line);
    }

    /* Write $content to file */
    cleanup();
    if (is_dir($DB_BACKUP_DIR)) {
      $temp = tempnam($DB_BACKUP_DIR."/", "");
      if (!copy($temp, $DB_BACKUP_DIR."/".$filename)) {
        ;//error_handle("Kunne ikke kopierer filen: <b>$temp</b> til <b>$filename</b>");
      }
      if (!file_exists($DB_BACKUP_DIR."/".$filename)) {
        error_handle("Filen: ".$DB_BACKUP_DIR."/".$filename." findes ikke"); //print("Filen eksister ikke")
      } else {
        $fp = fopen($DB_BACKUP_DIR."/".$filename, "w+");
        if ($fp) {
          fwrite ($fp, $content);
          fclose($fp);
        } // end if
      }// end else
    } else {
      ;//error_handle("$DB_BACKUP_DIR er ikke et bibliotek!"); //print("Ikke et dir!")
    }

  }
} // end function
Avatar billede angelenglen Nybegynder
21. februar 2003 - 22:12 #7
tefcke:
Svaret fra Avminarm virker fint, det eneste jeg mangler svar på er min forrige kommentar.
Hvis du dog kan hjælpe med det ville det være rart :-D
Avatar billede tefcke Nybegynder
21. februar 2003 - 22:16 #8
skal nok lige tilføje at jeg har en funktion som hedder error_handle() til at tage sig af mine fejlmeddelser (debug kode :), så du kan enten lade kaldende være udkommenteret, eller bare selv definerer funktionen.
Avatar billede angelenglen Nybegynder
21. februar 2003 - 22:18 #9
well umiddelbart er jeg jo godt tilfreds med avminarm's kode, så jeg tror jeg bliver ved den - kan ikke umiddelbart se den helt store fordel ved din fremfor avminarm's, eller omvendt.
Avatar billede tefcke Nybegynder
21. februar 2003 - 22:18 #10
ok, men den jeg har smidt ind, skriver det ned i en fil, og sørger for at der kun er de sidst $DB_BACKUP_MAXFILES backup i dir'et.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester