Det backupskriptet är löjligt och ingen borde göra en annan version av det. Jag har sett det skriptet förut, liksom liknande försök, och de har många problem:
- Avgränsar inte tabellnamn i back-ticks
- Hanterar inte NULL
- Hanterar inte teckenuppsättningar
- Hanterar inte binär data
- Säkerhetskopierar inte VIEWS
- Säkerhetskopierar inte TRIGGERS eller LAGRADE PROCEDURER eller LAGRADE FUNKTIONER eller HÄNDELSER
- Använder föråldrat mysql-tillägg (men det är därför du vill ha en PDO-version, eller hur?)
- Använder addslashes() istället för en riktig MySQL escape-funktion.
- Lägger till alla data för alla tabeller i en riktigt lång sträng innan hela innehållet matas ut. Det betyder att du måste kunna lagra hela din databas i en sträng, vilket med största sannolikhet kommer att spränga din maximala PHP-minnesgräns.
Se även mitt tidigare svar om David Walshs olyckliga säkerhetskopieringsskript:
Angående din kommentar:
Läs kommentarerna på sidan du länkade till. Många människor har identifierat problem, och några har korrigeringar eller åtminstone förslag.
Det faktum att det här skriptet lägger till allt i en sträng är en deal-breaker, tror jag, men det borde inte vara svårt att ändra skriptet för att öppna utdatafilen först , mata sedan ut varje rads data under loopen och stäng sedan filen efter loopen. Det är lite enkelt, jag är inte säker på varför manuset inte gör det. Men det är ganska tydligt att manuset inte testades särskilt bra.
Men hur som helst, jag skulle inte försöka uppfinna det här hjulet på nytt. Mysqldump eller mydumper gör det här jobbet bra. FWIW, du behöver inte köra mysqldump på samma server där databasen finns. Mysqldump stöder ett alternativ för --host
så att du kan köra mysqldump var som helst för att säkerhetskopiera en fjärrdatabas, så länge som brandväggar inte blockerar din klient från att ansluta. I grund och botten, om du kan ansluta en PHP-app till databasen från någon klientvärd, kan du ansluta mysqldump.
Om det verkligen inte är ett alternativ skulle jag använda databasdumpfunktionen i phpmyadmin. Dessa är mogna och väl beprövade och de dumpar allt korrekt. Här är en artikel som beskriver hur du använder dumpningsfunktionen:
http://www.techrepublic. com/blog/smb-technologist/import-and-export-databases-using-phpmyadmin/
[Kopierar mina kommentarer från ditt svar:]
Detta kommer in i kodgranskning, vilket inte är syftet med StackOverflow. Men kortfattat:
- inget stöd för NULL (du konverterar dem till '');
- inte konsekvent avgränsande tabellnamn;
- användning av icke-ANSI dubbla citattecken som strängavgränsare;
- att använda buffrade frågor på stora tabeller kommer att bryta PHP max minnesgräns;
- att lägga till alla rader för en stor tabell kommer att bryta PHP max minnesgräns;
- med addslashes() istället för PDO::quote();
- kontrollerar efter frågefel endast i slutet av funktionen;
- kontrollerar inte efter misslyckat filskapande;
- gzip-tillägget kanske inte laddas
- Stöder förmodligen fortfarande inte UTF8-data.
Ja, det här är bättre än det ursprungliga David Walsh-manuset. :-)
NULL är inte detsamma som '' i SQL (förutom i Oracle, men de överensstämmer inte med SQL-standarden i det här fallet). Se MySQL, bättre att infoga NULL eller tom sträng?
Jag läste fel koden på problemet med minnesgränsen. Du skriver utdata för varje rad, så det är okej (såvida inte raden innehåller en 1GB-blob eller något).
Men du bör inte bara mata ut en enda INSERT-sats med en kommaseparerad uppsättning rader. Till och med mysqldump --extended-insert
matar ut en ändlig längd av data och startar sedan en ny INSERT-sats. Kriteriet är om längden på INSERT-satsen passar inom alternativargumentet för --net-buffer-length
.
I ANSI SQL används enkla citattecken '' för att avgränsa strängliteraler eller datumliteraler. Dubbla citattecken "" används för att avgränsa identifierare som tabellnamn eller kolumnnamn. Som standard behandlar MySQL dem på samma sätt, men detta är icke-standard. Se Använder olika databaser olika namncitat? . Om du försöker importera dina backupdata till en MySQL-server där du har SET SQL_MODE=ANSI_QUOTES
, kommer importen att misslyckas.
Exempel:query('SELECT * FROM '.$table);
och faktiskt vart och ett av de andra fallen där du använder $table i en fråga. Du avgränsade bara tabellen en gång, i INSERT-satsen matar dina skript ut.
MySQL känner alltid igen back-ticks som identifierare avgränsare och enkla citattecken för strängar/datum. Men dubbla citattecken ändrar betydelse beroende på SQL_MODE jag nämnde. Du kan inte anta vilken SQL_MODE som är i kraft på MySQL-instansen du återställer på, så det är bäst om du använder back-ticks för identifierare och enstaka citattecken för strängar. Anledningen till att du skulle avgränsa dem när du frågar din tabell är att du kan ha tabellnamn som är reserverade SQL-ord, eller som innehåller specialtecken, etc.
Du kan infoga alla numeriska typer utan avgränsare. Endast strängar och datum behöver avgränsare. Se dev.mysql.com/doc/refman/5.6/en/literals.html