
💾 Sikkerhetskopiere og gjenopprette en MySQL-database via PHP
Å miste en database betyr å miste ordrer, brukere og innhold på sekunder. For en WordPress-nettsideeier er backup ikke noe som er «kjekt å ha», det er obligatorisk. Men å logge inn manuelt i phpMyAdmin hver dag sløser med tid, og når du trenger den, er sikkerhetskopien rett og slett ikke der.
Et PHP-skript løser problemet: du gir det databasetilgang, og det eksporterer struktur og data til en SQL-fil. Med fem minutters oppsett får du en repeterbar, programmerbar sikkerhetskopi du ikke glemmer å ta.
Neste: ferdige skript for MySQL-sikkerhetskopiering og gjenoppretting i PHP. Vi bryter ned hvordan de fungerer, hvor du henter påloggingsinformasjon, og hvordan du kjører automatisk sikkerhetskopiering etter en tidsplan slik at databasen din aldri står ubeskyttet.
💡 Rask oversikt:
- Koble til MySQL via
mysqli, hent tabelliste og eksporter struktur - Lag SQL-dump:
CREATE TABLEplussINSERTfor hver tabell, lagre til fil - Gjenopprett: les dump og kjør spørringer i én batch via
mysqli_multi_query - Automatisering via Cron (Linux) eller Oppgaveplanlegger (Windows) kjører skriptet uten din medvirkning
- Komprimering til
.gzog rotasjon av gamle kopier sparer plass og holder sikkerhetskopihistorikk
Trinn 1: Påloggingsinformasjon og miljø, hva du trenger før kjøring
Før du skriver kode, samle tre ting: MySQL-påloggingsinformasjon, en mappe for lagring av sikkerhetskopier og en forståelse av hvor skriptet skal kjøres.
For å koble til databasen trenger du vert (vanligvis localhost eller 127.0.0.1), brukernavn, passord og databasenavn. På et WordPress-nettsted ligger disse dataene i wp-config.php: konstantene DB_HOST (server), DB_USER (brukernavn), DB_PASSWORD (passord) og DB_NAME (databasenavn).
Opprett sikkerhetskopimappen utenfor nettstedets offentlige mappe. Plasser backups/-mappen ett nivå over public_html, slik at SQL-filer ikke er tilgjengelige fra nettleseren. Skrivetillatelser (chmod 755 eller chmod 775) er obligatorisk: uten dem vil fopen() og fwrite() feile med en feilmelding.
PHP-skriptet kjøres fra kommandolinjen: php backup.php. Kjøring via nett (via nettleser) er også mulig, men kommandolinjen er tryggere, ingen vil gjette skript-URL-en og dumpe databasen din.
Trinn 2: PHP-skript for databasesikkerhetskopiering
Skriptet gjør tre gjennomganger: henter tabelliste, for hver enkelt eksporterer det struktur (SHOW CREATE TABLE), deretter data (SELECT *). Resultatet settes sammen til én streng og skrives til en .sql-fil. Lagre koden som backup.php og kjør fra terminal.
1 <?php 2 3 $connection = mysqli_connect('localhost', 'user', 'pass', 'my_database'); 4 5 if (!$connection) { 6 die('Ошибка подключения: ' . mysqli_connect_error()); 7 } 8 9 $tables = []; 10 $result = mysqli_query($connection, "SHOW TABLES"); 11 while ($row = mysqli_fetch_row($result)) { 12 $tables[] = $row[0]; 13 } 14 15 $dump = ''; 16 foreach ($tables as $table) { 17 $dump .= 'DROP TABLE IF EXISTS ' . $table . ";\n"; 18 19 $create = mysqli_query($connection, "SHOW CREATE TABLE " . $table); 20 $row = mysqli_fetch_row($create); 21 $dump .= $row[1] . ";\n\n"; 22 23 $data = mysqli_query($connection, "SELECT * FROM " . $table); 24 $num_fields = mysqli_num_fields($data); 25 26 while ($row = mysqli_fetch_row($data)) { 27 $dump .= "INSERT INTO " . $table . " VALUES("; 28 for ($j = 0; $j < $num_fields; $j++) { 29 if (isset($row[$j])) { 30 $row[$j] = mysqli_real_escape_string($connection, $row[$j]); 31 $dump .= '"' . $row[$j] . '"'; 32 } else { 33 $dump .= 'NULL'; 34 } 35 if ($j < $num_fields - 1) { 36 $dump .= ','; 37 } 38 } 39 $dump .= ");\n"; 40 } 41 $dump .= "\n\n"; 42 } 43 44 $filename = 'backups/dump_' . date('Y-m-d_H-i-s') . '.sql'; 45 $handle = fopen($filename, 'w+'); 46 fwrite($handle, $dump); 47 fclose($handle); 48 49 echo "Бэкап сохранён: " . $filename . "\n"; 50 51 ?>
Hva som skjer her linje for linje. mysqli_connect() åpner en tilkobling, hvis tilgang nektes dør skriptet med en tydelig melding i stedet for å fortsette i stillhet. SHOW TABLES-løkken samler tabellnavn i en array.
For hver tabell returnerer SHOW CREATE TABLE nøyaktig én rad der det andre feltet er hele DDL-spørringen. Vi legger til DROP TABLE IF EXISTS foran den slik at dumpen kan brukes på en ren database uten konflikter.
SELECT * leser alle rader. Funksjonen mysqli_real_escape_string() unnslipper anførselstegn og spesialtegn inne i verdier, i motsetning til addslashes(), respekterer den tilkoblingskoding og overser ikke injeksjoner gjennom multibyt-sekvenser. NULL-verdier settes inn som NULL, ikke som tom streng.
Filnavnet inneholder kjøredato og -tid, praktisk for rotasjon. Filen åpnes i w+-modus (opprett eller overskriv) og mottar hele dumpen i én fwrite()-operasjon.
Trinn 3: Skript for databasegjenoppretting fra SQL-dump
Det omvendte skriptet leser .sql-filen og kjører spørringer mot databasen. I praksis veier dumper ofte titalls megabyte, så file_get_contents() og eksplodering med ; er ikke det beste alternativet for produksjon. Men for læringsformål og små databaser fungerer tilnærmingen.
Lagre som restore.php. Før kjøring, ta en full sikkerhetskopi av gjeldende database, gjenoppretting overskriver tabeller.
1 <?php 2 3 $connection = mysqli_connect('localhost', 'root', '', 'test'); 4 5 if (!$connection) { 6 die('Ошибка подключения: ' . mysqli_connect_error()); 7 } 8 9 $filename = 'backups/dump_2026-06-14_12-00-00.sql'; 10 11 if (!file_exists($filename)) { 12 die('Файл дампа не найден: ' . $filename); 13 } 14 15 $contents = file_get_contents($filename); 16 17 if (mysqli_multi_query($connection, $contents)) { 18 do { 19 if ($result = mysqli_store_result($connection)) { 20 mysqli_free_result($result); 21 } 22 } while (mysqli_next_result($connection)); 23 echo "База восстановлена из: " . $filename . "\n"; 24 } else { 25 echo "Ошибка восстановления: " . mysqli_error($connection) . "\n"; 26 } 27 28 mysqli_close($connection); 29 30 ?>
Den viktigste forskjellen fra linje-for-linje mysqli_query() er mysqli_multi_query(). Den aksepterer en streng med flere SQL-spørringer og kjører dem sekvensielt i ett kall. do...while-løkken med mysqli_next_result() er obligatorisk: uten den vil påfølgende spørringer ikke bli kjørt, og tilkoblingen vil henge.
mysqli_store_result() henter resultatet av den gjeldende spørringen, og mysqli_free_result() frigjør minne. Hvis spørringen er INSERT eller CREATE TABLE, vil resultatet være false, og det er normalt: skriptet går bare videre til neste.
Merk: skriptet gjør ikke DROP DATABASE og gjenskaper ikke selve databasen. Det forventer at test-databasen allerede eksisterer. For sikkerhets skyld kan den første linjen i dumpen inneholde CREATE DATABASE IF NOT EXISTS.
Trinn 4: Automatisering av sikkerhetskopiering via Cron og komprimering
Manuell kjøring fungerer for engangsoppgaver. Men på et aktivt nettsted bør sikkerhetskopiering skje uten deg, hver natt mens du sover.
På en Linux-server legger du til en oppgave i Cron: crontab -e og linjen 0 3 * * * php /path/to/backup.php kjører skriptet hver dag kl. 03.00. På Windows, Oppgaveplanlegger med handlingen «start et program» php.exe og argument-sti til skriptet.
To forbedringer som gjør et læreskript produksjonsklart:
Komprimering. Etter å ha skrevet .sql-filen, legg til exec("gzip " . $filename);, dumpstørrelsen vil krympe 5-10 ganger. For gjenoppretting pakker gunzip ut filen igjen.
Rotasjon. Behold sikkerhetskopier for de siste 7 dagene, slett resten. Enkelt alternativ, legg til opprydding av filer eldre enn N dager i starten av skriptet:
1 $retention_days = 7; 2 $backup_dir = 'backups/'; 3 foreach (glob($backup_dir . '*.sql.gz') as $file) { 4 if (filemtime($file) < time() - $retention_days * 86400) { 5 unlink($file); 6 } 7 }
Som et resultat har du et autonomt system: skriptet kjører etter tidsplan, oppretter komprimert sikkerhetskopi med dato i filnavnet og rydder opp i gammelt. Stødige hender og 20 minutters oppsett erstatter en betalt plugin.
Videoen over viser hele den automatiske sikkerhetskopieringssyklusen: fra konfigurasjonsfil til sjekk av komprimert .sql.gz i backups/-mappen. Tilnærmingen er nøyaktig den samme som beskrevet i denne artikkelen, med ekstra feilsjekker og logging.
⁉️🤔 FAQ
Er det trygt å lagre MySQL-passord i et PHP-skript?
Å lagre påloggingsinformasjon i klartekst inne i et skript er akseptabelt bare hvis filen ligger utenfor nettstedets offentlige mappe og er utilgjengelig fra nettleseren. Bedre å flytte påloggingsinformasjon til en separat
config.phputenforpublic_htmlog inkludere viarequire. Enda mer pålitelig, send passordet gjennom miljøvariabel:getenv('DB_PASS').
Kan jeg bare sikkerhetskopiere bestemte tabeller?
Ja. Erstatt
SHOW TABLESmed en eksplisitt array med navn:$tables = ['wp_posts', 'wp_postmeta', 'wp_options'];. Eller ekskluder uviktige tabeller viaif (!in_array($table, ['wp_litespeed_cache', 'wp_actionscheduler_logs'])). I praksis tar cache- og loggtabeller opp en betydelig del av databasestørrelsen og er ikke nødvendige for gjenoppretting.
Hvor mye plass tar en sikkerhetskopi av en gjennomsnittlig WordPress-nettsidedatabase?
Ukomprimert SQL-dump av en database med 500 innlegg og 15 plugins veier 15-40 MB. Etter
gzip, 2-8 MB. Over en måned med daglige sikkerhetskopier med komprimering akkumuleres 100-300 MB, for en server med 20 GB disk er dette ubetydelig. Rotasjon i 7 dager holder okkupert plass innenfor 50-100 MB.
Hva gjør jeg hvis sikkerhetskopifilen er ødelagt?
Før gjenoppretting, sjekk integritet:
gunzip -t dump.sql.gzfor komprimert,head -n 20 dump.sqlfor ukomprimert, forsikre deg om at filen starter med SQL-kommentarer, ikke binært søppel. Ikke gjenopprett en ødelagt dump, du vil miste data. Det er nettopp derfor du beholder minst 2-3 nyeste kopier.
Hvordan skiller denne tilnærmingen seg fra WordPress backup-plugins?
En plugin som UpdraftPlus gir et webgrensesnitt, inkrementelle sikkerhetskopier og skyopplasting «ut av esken». Et PHP-skript er full kontroll over prosessen uten ekstra kode i admin. For en utvikler som allerede jobber med serveren, er skriptet raskere og mer transparent. For en kunde uten konsolltilgang er en plugin mer praktisk.
Manuelt skript, mysqldump eller plugin, hva du skal velge for din oppgave
Et PHP-sikkerhetskopiskript gir deg det viktigste, forståelse av nøyaktig hva som skjer med databasen din under sikkerhetskopiering. Du stoler ikke på en svart boks, du kontrollerer hver spørring.
Hvis nettstedet er i produksjon og hastighet betyr noe, bruk mysqldump. Én kommando mysqldump -u user -p db_name | gzip > dump.sql.gz gjør det samme, men ganger raskere, fordi det fungerer på MySQL-motornivå, ikke rad-for-rad SELECT. Et PHP-skript er for læringsformål, tilpassede scenarioer (sikkerhetskopiering av ikke hele databasen, men resultater av en spesifikk spørring) og miljøer der mysqldump ikke er tilgjengelig.
Hvis nettstedet er på WordPress og du ikke vil dykke ned i konsoll, vil enhver backup-plugin lukke oppgaven uten kode. UpdraftPlus, BackWPup, Duplicator henter både database og nettstedsfiler.
Start med et manuelt skript, forstå hvordan en SQL-dump dannes. Sett deretter opp Cron og komprimering. Siste trinn, verifiser gjenoppretting på en testserver: en sikkerhetskopi uten gjenopprettingsverifisering regnes ikke som fullført. Hvilket verktøy for databasesikkerhetskopiering bruker du? Skriv i kommentarene.



