.sql file restoren
Nu wil ik ook graag een script wat de laatste file automatisch restored mocht de database corrupt zijn, de check hiervoor heb ik al, ik loop alleen vast bij het restoren opzich.
Ik heb het bestand uitgelezen en hoopte dat als ik de lap tekst in een mysql_query(); zou stoppen het zou werken, maar dat is dus niet zo.
Om te testen heb ik een kleine db aangemaakt, en daar is het volgende bestand van gemaakt:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
#Create table testtabel
CREATE TABLE `testtabel` (
`veld1` int(11) NOT NULL auto_increment,
`veld2` varchar(255) NOT NULL,
`veld3` decimal(6,2) NOT NULL,
PRIMARY KEY (`veld1`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
#Dump data
INSERT INTO testtabel SET veld1='1',veld2='dfsalk;jafdskjl',veld3='2.50';
INSERT INTO testtabel SET veld1='2',veld2='fdsjlkfdsjlk',veld3='8.60';
INSERT INTO testtabel SET veld1='3',veld2='sfd879243fds980ufdsjokdsf0u9832f0u9dsffds',veld3='887.00';
CREATE TABLE `testtabel` (
`veld1` int(11) NOT NULL auto_increment,
`veld2` varchar(255) NOT NULL,
`veld3` decimal(6,2) NOT NULL,
PRIMARY KEY (`veld1`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
#Dump data
INSERT INTO testtabel SET veld1='1',veld2='dfsalk;jafdskjl',veld3='2.50';
INSERT INTO testtabel SET veld1='2',veld2='fdsjlkfdsjlk',veld3='8.60';
INSERT INTO testtabel SET veld1='3',veld2='sfd879243fds980ufdsjokdsf0u9832f0u9dsffds',veld3='887.00';
Zodra ik dit in de mysql_query(); stop, komt er de volgende foutmelding: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '; #Dump data INSERT INTO testtabel SET veld1='1',veld2='dfsalk;jafdskjl',veld3' at line 8
Hij accepteert de create tabel dus wel, maar zodra de data ingevoegd gaat worden, gaat het fout.
Wat moet ik doen om dit wel te doen lukken?
Het werkt nu.
@GaMer, Die foute syntax was me nog niet eens opgevallen, maar ik had het script dat die syntax maakte wel uit de script library hier.
Die syntax werkt ook wel maar alleen met MySQL, dus het is aan te raden een andere syntax te gebruiken.
http://www.phphulp.nl/php/scripts/7/261/
En daar heb ik het volgende van gemaakt:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<?php
mysql_connect("localhost","user","ww");
mysql_select_db("db");
//query to receive table names
$query = mysql_query('SHOW TABLE STATUS') or die(mysql_error());
$sql_backup = '';
if (mysql_num_rows($query) == 0) //database is leeg, restoren met de meest recente backup
{
$map = 'mysql_backups';
$dir = opendir($map);
while(false !== ($file=readdir($dir)))
{
if(($file!=".") && ($file!=".."))
{
$backups[] = $file;
}
}
//sorteren van hoog naar laag, oftewel, de meest recente als eerst
rsort($backups);
$file = 'mysql_backups/'.$backups[0];
chmod($file,0777);
$open = fopen($file, "r");
$data = fread($open, filesize($file));
fclose($open);
$array = explode(';',$data);
foreach ($array as $array2)
{
mysql_query($array2) or die (mysql_error());
}
//e-mail sturen dat de database teruggezet is
$bericht = "Er is geconstateerd dat de database leeg was.
Zojuist is de laatste database backup teruggezet.";
$headers = "FROM: ....\r\n";
$headers .= "Reply-To: ...\r\n";
mail('[email protected]','Database restored!',$bericht,$headers);
}
else //database is niet leeg, dus backuppen
{
//whileloop to loop trough every table
while($row = mysql_fetch_assoc($query))
{
//show sql query to rebuild the query
$sql = 'SHOW CREATE TABLE '.$row['Name'].'';
//exucte error or give a error
$query2 = mysql_query($sql) or die(mysql_error());
//create sql
$sql_backup.="\r\n#Create table ".$row['Name']."\r\n\r\n";
$out = mysql_fetch_assoc($query2);
$sql_backup.=$out['Create Table'].";\r\n\r\n";
$sql_backup.="#Dump data\r\n\r\n";
//SQL code to select everything for table
$sql = 'SELECT * FROM '.$row['Name'];
$out = mysql_query($sql);
$sql_code = '';
//loop trough the colloms
while($code = mysql_fetch_array($out,MYSQL_ASSOC))
{
$sql_code .= "INSERT INTO ".$row['Name']." (";
foreach($code as $insert => $value)
{
$sql_code .=$insert.", ";
}
$sql_code = substr($sql_code, 0, -2);
$sql_code .= ") VALUES (";
foreach($code as $insert => $value)
{
$sql_code.="'".addslashes($value)."', ";
}
$sql_code = substr($sql_code, 0, -2);
$sql_code .= ")";
$sql_code .= ";\r\n";
}
$sql_backup.= $sql_code;
}
//function to be able to store data in a txt file
//store data
$text = $sql_backup;
$bestand = 'mysql_backups/'.date("YmdHis").'.txt';
file_put_contents($bestand, $text);
}
?>
mysql_connect("localhost","user","ww");
mysql_select_db("db");
//query to receive table names
$query = mysql_query('SHOW TABLE STATUS') or die(mysql_error());
$sql_backup = '';
if (mysql_num_rows($query) == 0) //database is leeg, restoren met de meest recente backup
{
$map = 'mysql_backups';
$dir = opendir($map);
while(false !== ($file=readdir($dir)))
{
if(($file!=".") && ($file!=".."))
{
$backups[] = $file;
}
}
//sorteren van hoog naar laag, oftewel, de meest recente als eerst
rsort($backups);
$file = 'mysql_backups/'.$backups[0];
chmod($file,0777);
$open = fopen($file, "r");
$data = fread($open, filesize($file));
fclose($open);
$array = explode(';',$data);
foreach ($array as $array2)
{
mysql_query($array2) or die (mysql_error());
}
//e-mail sturen dat de database teruggezet is
$bericht = "Er is geconstateerd dat de database leeg was.
Zojuist is de laatste database backup teruggezet.";
$headers = "FROM: ....\r\n";
$headers .= "Reply-To: ...\r\n";
mail('[email protected]','Database restored!',$bericht,$headers);
}
else //database is niet leeg, dus backuppen
{
//whileloop to loop trough every table
while($row = mysql_fetch_assoc($query))
{
//show sql query to rebuild the query
$sql = 'SHOW CREATE TABLE '.$row['Name'].'';
//exucte error or give a error
$query2 = mysql_query($sql) or die(mysql_error());
//create sql
$sql_backup.="\r\n#Create table ".$row['Name']."\r\n\r\n";
$out = mysql_fetch_assoc($query2);
$sql_backup.=$out['Create Table'].";\r\n\r\n";
$sql_backup.="#Dump data\r\n\r\n";
//SQL code to select everything for table
$sql = 'SELECT * FROM '.$row['Name'];
$out = mysql_query($sql);
$sql_code = '';
//loop trough the colloms
while($code = mysql_fetch_array($out,MYSQL_ASSOC))
{
$sql_code .= "INSERT INTO ".$row['Name']." (";
foreach($code as $insert => $value)
{
$sql_code .=$insert.", ";
}
$sql_code = substr($sql_code, 0, -2);
$sql_code .= ") VALUES (";
foreach($code as $insert => $value)
{
$sql_code.="'".addslashes($value)."', ";
}
$sql_code = substr($sql_code, 0, -2);
$sql_code .= ")";
$sql_code .= ";\r\n";
}
$sql_backup.= $sql_code;
}
//function to be able to store data in a txt file
//store data
$text = $sql_backup;
$bestand = 'mysql_backups/'.date("YmdHis").'.txt';
file_put_contents($bestand, $text);
}
?>
misschien dat andere mensen nog wat met deze code kunnen, hij werkt namelijk prima nu.
hetgeen deze code doet is kijken of de database gevuld is met data, als dat het geval is, dan een backup maken en wegschrijven naar een directory, als de database leeg blijkt te zijn kijkt hij voor de meest recente backup en zet die terug.
Het werkt uiteraard alleen als alle tabellen weg zijn en niet als de hele database weg is, maar dat is weer een ander verhaal.
Gewijzigd op 01/01/1970 01:00:00 door Stefan van Iwaarden
Gebruik échte tools om backups te maken, bv. Backup van MySQL (zie de handleiding).
De huidige scripts zijn echt werkelijk waar nergens beveiligt hiertegen, en daarom moet ik dan ook een volledig nieuwe website ontwikkelen, en dit script is om de hinder als de database weer geleegt is zo kort mogelijk te houden.
Gewijzigd op 01/01/1970 01:00:00 door Stefan van Iwaarden
Quote:
vrijwel elke dag last heeft van mysql injection, waarschijnlijk iemand die elke dag even langskomt, en daarbij de volledige database leegt.
Haha, lache! Dat ze zo'n script geaccepteerd hebben dan. Niet eens zelf even getest? Ach, de opdrachtgevers zullen wel geen ervaring zelf hebben ;-). Ook slecht dan van de scripter om zoiets af te leveren, zou mezelf kapot schamen...
Edit: Misschien een wat makkelijker, maar toch snelle oplossing. Weet niet precies over wat voor een grootte qua website (scripting) praten, maar misschien is het een idee om bij ieder formulier (of gewoon bovenaan de indexpagina als alle pagina's included worden) even onderstaande functie over de $_POST variabele te laten gaan. Datzelfde geldt voor de $_GET variabele.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
<?php
function mysql_real_escape_array($array) {
if(is_array($array)) {
foreach($array as $key => $value) {
$array[$key] = mysql_real_escape_string($value);
}
}
return $array;
}
?>
function mysql_real_escape_array($array) {
if(is_array($array)) {
foreach($array as $key => $value) {
$array[$key] = mysql_real_escape_string($value);
}
}
return $array;
}
?>
Gewijzigd op 01/01/1970 01:00:00 door Jesper Diovo
Dit meen je niet! Anno 2008 zijn er nog sukkels die dit soort waardeloze scripts weten te produceren of online hebben staan... Hoe is het mogelijk!
Djemo schreef op 15.04.2008 16:53:
Haha, lache! Dat ze zo'n script geaccepteerd hebben dan. Niet eens zelf even getest? Ach, de opdrachtgevers zullen wel geen ervaring zelf hebben ;-). Ook slecht dan van de scripter om zoiets af te leveren, zou mezelf kapot schamen...
Edit: Misschien een wat makkelijker, maar toch snelle oplossing. Weet niet precies over wat voor een grootte qua website (scripting) praten, maar misschien is het een idee om bij ieder formulier (of gewoon bovenaan de indexpagina als alle pagina's included worden) even onderstaande functie over de $_POST variabele te laten gaan. Datzelfde geldt voor de $_GET variabele.
Quote:
vrijwel elke dag last heeft van mysql injection, waarschijnlijk iemand die elke dag even langskomt, en daarbij de volledige database leegt.
Haha, lache! Dat ze zo'n script geaccepteerd hebben dan. Niet eens zelf even getest? Ach, de opdrachtgevers zullen wel geen ervaring zelf hebben ;-). Ook slecht dan van de scripter om zoiets af te leveren, zou mezelf kapot schamen...
Edit: Misschien een wat makkelijker, maar toch snelle oplossing. Weet niet precies over wat voor een grootte qua website (scripting) praten, maar misschien is het een idee om bij ieder formulier (of gewoon bovenaan de indexpagina als alle pagina's included worden) even onderstaande functie over de $_POST variabele te laten gaan. Datzelfde geldt voor de $_GET variabele.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
<?php
function mysql_real_escape_array($array) {
if(is_array($array)) {
foreach($array as $key => $value) {
$array[$key] = mysql_real_escape_string($value);
}
}
return $array;
}
?>
function mysql_real_escape_array($array) {
if(is_array($array)) {
foreach($array as $key => $value) {
$array[$key] = mysql_real_escape_string($value);
}
}
return $array;
}
?>
De klant zelf kan hier misschien niets aan doen, dat zal wel een flut programmeur zijn geweest dan om zoiets bij een klant af te leveren. Ik zal nie ontkennen dat ik vanaf begin af aan 100% veilige scripts maakte (en nu nog niet 100%, wel op SQL niveau uiteraard). Maar ik vind het gewoon slecht dat zoiets bij een klant wordt afgeleverd terwijl SQL-injection bij elke redelijke programmeur toch wel bekend is, en ook de middelen daar tegen.
Gewoon een dikke schadeclaim naar de programmeur toesturen en hem voor de kosten op laten draaien. Hij heeft het ook veroorzaakt, dit soort onzin hoef je echt niet te accepteren.
Echter heb ik bij bovenstaand script een probleem, zodra ik hem laat draaien op een database van een ruime 9 mb met zo'n 200.000 records duurt het zo'n 3 minuten voor hij klaar is, daar heb ik geen problemen mee, maar zodra hij klaar is komt er een standaard downloadschermpje in beeld waarmee ik het php bestand opzich kan downloaden, als je dat doet krijg je een leeg .php bestand.
Tevens wordt er geen backup opgeslagen in de map.
Wat gaat er fout, bij een test op een kleinere database met een 10 tal tabellen en 500 records ging het wel goed, enige wat er gebeurt is, is de inloggegevens aangepast.
Max execution time is dan bereikt. Misschien kun je toch beter voor mijn functie-oplossing gaan. Zo'n backup telkens maken en er weer opzetten zal op den duur ook z'n errors gaan opleveren.
de time_limit heb ik op 0 gezet, en dat werkte, dus hij loopt gewoon helemaal uit.
30 seconden per query om de boel te beveiligen: 600 minuten, 10 uur werk.
Je had dus al klaar kunnen zijn...
maar dat was niet mijn vraag, het gaat nu om dit kleine scriptje, de rest zal wel lukken.
Gewijzigd op 01/01/1970 01:00:00 door Stefan van Iwaarden