Hi,
I found a script online which automatically saves my databases and stores them for two weeks, started every night with a cronjob. Files older then that inside the folder will be automatically deleted. Now the script deletes itself, 'cause the script file is older then two weeks!
lolSure there is a way to prevent the script file from deleted, make an exception inside the code. This is the script I am using:
<?php
######## Einstellungen DB-Backup #############################################
$db_name = "d01b41f9";
$db_passwd = "xxx";
$sql_file = "dump_" . $db_name . "_" . date('Ymd_Hi') . ".sql";
####################################################################
exec("mysqldump -u $db_name -p'$db_passwd' --allow-keywords --add-drop-table --complete-insert --quote-names $db_name > $sql_file");
exec("gzip $sql_file");
$datei = $sql_file . ".gz";
$link = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
$link = str_replace(basename(__FILE__),$datei,$link);
echo "Downloadlink: <a href='" . $link . "'>" . $datei . "</a><br>";
######## Dateien löschen, die älter als 14 Tage sind #############################################
/*
* Created on 30.01.2010 by Nico Schubert
*/
$dir =
$_SERVER["DOCUMENT_ROOT"].dirname($_SERVER['PH
P_SELF']).'/';
$folder = dir($dir);
while ($dateiname = $folder->read()) {
if (filetype($dir.$dateiname) != "dir") {
if (strtotime("-2 weeks") >
@filemtime($dir.$dateiname)) {
if (@unlink($dir.$dateiname) != false)
echo $dateiname.' wurde gelöscht<br>';
else
echo $dateiname.' konnte nicht
gelöscht werden<br>';
}
}
}
echo "Suchen nach zu löschenden Dateien... Fertig";
$folder->close();
exit;
?>
Would be great if someone could help me out and tell me where I can change the code so the script itself wouldn't be deleted anymore.
I am not sure whether this will work as I haven't tested it yet.
<?php
######## Einstellungen DB-Backup #############################################
$db_name = "d01b41f9";
$db_passwd = "xxx";
$sql_file = "dump_" . $db_name . "_" . date('Ymd_Hi') . ".sql";
####################################################################
exec("mysqldump -u $db_name -p'$db_passwd' --allow-keywords --add-drop-table --complete-insert --quote-names $db_name > $sql_file");
exec("gzip $sql_file");
$datei = $sql_file . ".gz";
$link = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
$link = str_replace(basename(__FILE__),$datei,$link);
echo "Downloadlink: <a href='" . $link . "'>" . $datei . "</a><br>";
######## Dateien löschen, die älter als 14 Tage sind #############################################
/*
* Created on 30.01.2010 by Nico Schubert
*/
$dir =
$_SERVER["DOCUMENT_ROOT"].dirname($_SERVER['PH
P_SELF']).'/';
$folder = dir($dir);
while ($dateiname = $folder->read()) {
if (filetype($dir.$dateiname) != "dir"
&& pathinfo($dir.$dateiname, PATHINFO_EXTENSION) != "php")
{
if (strtotime("-2 weeks") >
@filemtime($dir.$dateiname)) {
if (@unlink($dir.$dateiname) != false)
echo $dateiname.' wurde gelöscht<br>';
else
echo $dateiname.' konnte nicht
gelöscht werden<br>';
}
}
}
echo "Suchen nach zu löschenden Dateien... Fertig";
$folder->close();
exit;
?>
Basically I just added: && pathinfo($dir.$dateiname, PATHINFO_EXTENSION) != "php" exactly after: if (filetype($dir.$dateiname) != "dir". I think you can also use: && pathinfo($dir.$dateiname, PATHINFO_EXTENSION) === "gz", if gz is the extension of file(s) to be deleted (as it will later be filtered by number of weeks set).
Thank you, I will try it!
Do note: judging from the first few lines, it looks like the script is set up to save the database backup on a "web-accessible" place (based on the fact it provides a download link).
Keep in mind that having the database backed up in a web-accessible location is a security risk for both you and your users.
That said, if you put the script in a directory that is not accessible from an http url, then you are fine.
It isn't. I changed the line to:
echo "Datei erstellt: " . $datei . "<br>";
Thanks for the hint.
That just doesn't explicitly give out the url, but if you have the php file in the same place as for example the index.php of your forum, the result is still kinda the same, because the file name is not random at all and with a bit of luck can be guessed. ;)
In most hosting you have the "root" of your space, then you have a "public" or "http" or something similar directory that is the only one accessible from "the outside", so:
\
|-\log
|-\http
|-\forum
etc.
anything under "http" can be read via an URL, instead things in other locations (e.g. "log") cannot. If you create a directory "backups" like this:
\
|-\backups
|-\log
|-\http
|-\forum
etc.
and put the script there, then you are save, otherwise you may not be.
Sorry for the offtopic , but if you have ssh access you can achieve this with mysqlbackup tool in a more quick and safer way .
Mysqlbackup using ssh is also useful but php script should be safe subject to the practise suggested by emanuele above.
Thank you all, but I need more help. :-[
At my webspace I can set domains to all my folders. I have no HTTP folder as mentioned by
@emanuele. What I can do, so the support told me via email, is to save the backup files in the absolute server path
/www/htdocs/(my-FTP-login)/(path-on-FTP). The backup script must be reachable with HTTP because the cronjob must find the script, so I think I must save it in a folder reachable with a (sub)domain, right? In the cronjob settings must be a path to the script defined with HTTP or HTTPS.
So for the script to work, I must change it to save the files here:
/www/htdocs/(my-FTP-login)/(path-on-FTP). I don't know how. :-[ I wish there would me a much more safer way as for in the script the database name and password is shown!
No. The backup script can be hidden. You can run your cronjob as follows:
* * * * * sshusername php -q /yourhiddenpathfromhttp/yourscript.php
Change the scheduled time (*****) and your sshusername accordingly.
Hm... I don't think you understand. This is the settings page for the cronjob. There is no command line, only path to the php file and the time the script will be started.
Noted. I guess that is your issue with your hosting. If you are using VPS, you should be able to do beyond that.
VPS? Not that I know. ;) It's just hosted webspace and databases.
Put your absolute path in:
$dir =
$_SERVER["DOCUMENT_ROOT"].dirname($_SERVER['PH
P_SELF']).'/';
something like:
$dir = '/www/htdocs/(my-FTP-login)/(path-on-FTP)';
should do.
Doesn't work. The backup file is saved where the script is. I tried:
$dir = '/www/htdocs/(ftp-login-name)/backup/';
Edit: The older files in the backup folder were deleted, this seems to work. But the new backup files are saved in the wrong directory. So we must tell the backup script to create the files in another folder. Could it be here?
$sql_file = "dump_" . $db_name . "_" . date('Ymd_Hi') . ".sql";
What about changing to something like this:
> /backupfolderpath/$sql_file");
Which line please? There are a few $sql_file in the script...
Sorry, I am an absolute noob with PHP. I thought the line to change must be:
$sql_file = "dump_" . $db_name . "_" . date('Ymd_Hi') . ".sql";
to something like:
$sql_file = "/www/htdocs/(my-FTP-login)/(path-on-FTP)/dump_" . $db_name . "_" . date('Ymd_Hi') . ".sql";
At the end of this one:
exec("mysqldump -u $db_name -p'$db_passwd' --allow-keywords --add-drop-table --complete-insert --quote-names $db_name > $sql_file");
Okay, but now it isn't a .gz file anymore, the backup (in the right folder, yippie!) is an SQL file. :o
<?php
######## Einstellungen DB-Backup #############################################
$db_name = "d01b41f9";
$db_passwd = "FUkRXMwV23R5qk5L";
$destination = '/absolute/path/to/a/safe/location/'; // Do not forget the leading /
$sql_file = "dump_" . $db_name . "_" . date('Ymd_Hi') . ".sql";
####################################################################
$output = $destination . $sql_file;
exec("mysqldump -u $db_name -p'$db_passwd' --allow-keywords --add-drop-table --complete-insert --quote-names $db_name > $output");
exec("gzip $sql_file");
$datei = $sql_file . ".gz";
$link = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
$link = str_replace(basename(__FILE__),$datei,$link);
echo "Downloadlink: <a href='" . $link . "'>" . $datei . "</a><br>";
######## Dateien löschen, die älter als 14 Tage sind #############################################
/*
* Created on 30.01.2010 by Nico Schubert
*/
$dir = $destination;
$folder = dir($dir);
while ($dateiname = $folder->read()) {
if (filetype($dir.$dateiname) != "dir") {
if (strtotime("-2 weeks") >
@filemtime($dir.$dateiname)) {
if (@unlink($dir.$dateiname) != false)
echo $dateiname.' wurde gelöscht<br>';
else
echo $dateiname.' konnte nicht
gelöscht werden<br>';
}
}
}
echo "Suchen nach zu löschenden Dateien... Fertig";
$folder->close();
exit;
?>
Thank you, Emanuele. Your script worked, but....
The backup is again an uncompressed SQL file. Why that? :o
That's because it is a similar solution to mine but longer one with minor mistakes I think (this include my earlier suggestion as well).
@emanuele changed the variable to $output but forget to change the same variable $sql_file to $output below it. This is because the file is in other path now and need the same to be defined for the one below. I think.
I understand not a word. I think. :D
I mean what about changing the latter $sql_file to $output:
exec("gzip $sql_file");
$datei = $sql_file . ".gz";
Otherwise the code is looking for the sql file and gzipped sql file at the script location and not in the set location? I think.
Now the backup file has the .gz ending, but it is not packed (203 MB file size, while packed backup files are 36 MB). :o
I tried this line:
exec("gzip $destination . $sql_file");
...so the gzip procedure will find the file in the other location, but it didn't work. File size is still 203 MB.
Code is now:
$destination = '/www/htdocs/xxx/backup/'; // Do not forget the leading /
$sql_file = "dump_" . $db_name . "_" . date('Ymd_Hi') . ".sql";
####################################################################
$output = $destination . $sql_file . ".gz";
exec("mysqldump -u $db_name -p'$db_passwd' --allow-keywords --add-drop-table --complete-insert --quote-names $db_name > $output");
exec("gzip $destination . $sql_file");
Because interpretation changes the meaning of things. :P
<?php
######## Einstellungen DB-Backup #############################################
$db_name = "d01b41f9";
$db_passwd = "FUkRXMwV23R5qk5L";
$destination = '/absolute/path/to/a/safe/location/'; // Do not forget the leading /
$sql_file = "dump_" . $db_name . "_" . date('Ymd_Hi') . ".sql";
####################################################################
$output = $destination . $sql_file;
exec("mysqldump -u $db_name -p'$db_passwd' --allow-keywords --add-drop-table --complete-insert --quote-names $db_name > $output");
exec("gzip $output");
echo "Backup created<br>";
######## Dateien löschen, die älter als 14 Tage sind #############################################
/*
* Created on 30.01.2010 by Nico Schubert
*/
$dir = $destination;
$folder = dir($dir);
while ($dateiname = $folder->read()) {
if (filetype($dir.$dateiname) != "dir") {
if (strtotime("-2 weeks") >
@filemtime($dir.$dateiname)) {
if (@unlink($dir.$dateiname) != false)
echo $dateiname.' wurde gelöscht<br>';
else
echo $dateiname.' konnte nicht
gelöscht werden<br>';
}
}
}
echo "Suchen nach zu löschenden Dateien... Fertig";
$folder->close();
exit;
?>
Great! This code worked! And you know what? I know what the solution was! Seems logical now that I see it. I think! :D
Thank you both,
@emanuele and
@ahrasis, for your help with this stupid thing! O:-)
yw! :)