{"id":1572,"date":"2009-12-21T17:58:45","date_gmt":"2009-12-21T17:58:45","guid":{"rendered":"http:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm"},"modified":"2009-12-21T17:58:45","modified_gmt":"2009-12-21T17:58:45","slug":"script-to-back-up-a-mysql-database-eg-for-wordpress-blogs","status":"publish","type":"post","link":"https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm","title":{"rendered":"Script to back up a MySQL database (e.g. for WordPress blogs)"},"content":{"rendered":"<p><a href=\"http:\/\/www.codinghorror.com\/blog\/archives\/001315.html\">Jeff Atwood&#8217;s recent blog failure<\/a> has probably served as a timely reminder to website owners across the &#8216;net &#8211; and I&#8217;m pleased to see that Jeff got his site back (some of us would be less lucky).\u00c2\u00a0 At the time, I tweeted this:<\/p>\n<blockquote cite=\"http:\/\/twitter.com\/markwilsonit\/status\/6582653794\"><p>&#8220;RT @<a href=\"http:\/\/twitter.com\/edbott\">edbott<\/a>: Every webmaster&#8217;s nightmare:  ^MW Feeling sorry for @<a href=\"http:\/\/twitter.com\/codinghorror\">codinghorror<\/a> and thanking @<a href=\"http:\/\/twitter.com\/alexcoles\">alexcoles<\/a> for my backups&#8221;<\/p><\/blockquote>\n<p>To which the response from <a href=\"http:\/\/www.ascomi.net\/\">my hosting provider<\/a> came back as &#8220;er&#8230; what backups?!&#8221;.\u00c2\u00a0 Thankfully, that was an attempt at humour (either that or <a href=\"http:\/\/www.alexcoles.com\/\">Alex<\/a> had forgotten that he&#8217;d helped me set some backups last summer &#8211; it helps to be on first name terms with the guys who look after your Internet presence)!<\/p>\n<p>In common with many blogs, markwilson.it runs on self-hosted WordPress and the key to its existence is a MySQL database.\u00c2\u00a0 Themes, etc. can be recreated&#8230; the data cannot (at least not easily).<\/p>\n<p>This is where the following script comes in.\u00c2\u00a0 Run as a <code>cron<\/code> job on my host&#8217;s server, I have it set up to make a copy of my WordPress database and e-mail it to me (which means I have archive copies in my Google mail).\u00c2\u00a0 It took some tweaking (by Alex)\u00c2\u00a0to run without errors and I&#8217;d like to link to it&#8217;s original source but <a href=\"http:\/\/www.phpfreaks.com\/script\/view\/11.php\">the link I have<\/a> appears to be dead &#8211; I&#8217;ve left the original author&#8217;s comments intact though &#8211; hopefully he won&#8217;t mind:<\/p>\n<p><dirtycode:noclick><br \/>\n#! \/usr\/bin\/php -q<br \/>\n<?php\n\/* Database Backup Utility 1.0 By Eric Rosebrock, http:\/\/www.phpfreaks.com\nWritten: July 7th, 2002 12:59 AM\n\nIf running from shell, put this above the <?php \"#! \/usr\/bin\/php -q\" without the quotes!!!\n\nThis script is dedicated to \"Salk\". You know who you are \n\nThis script runs a backup of your database that you define below. It then gzips the .sql file and emails it to you or ftp's the file to a location of your choice.\n\nIt is highly recommended that you leave gzip on to reduce the file size.\n\nYou must chown the directory this script resides in to the same user or group your webserver runs in, or CHMOD it to writable. I do not recommend chmod 777 but it's a quick solution. If you can setup a cron, you can probably chown your directory!\n\nIMPORTANT!!! I recommend that you run this outside of your web directory, unless you manually want to run this script. If you do upload it inside your web directory source tree, I would at least apply Apache access control on that directory. You don't want people downloading your raw databases!\n\nThis script is meant to be setup on a crontab and run on a weekly basis. You will have to contact your system administrator to setup a cron tab for this script.  Here's an example crontab:\n\n0 0-23 * * * php \/path\/to\/thisdirectory\/dbsender.php > dev\/null<\/p>\n<p>*\/<\/p>\n<p>\/\/ configure your database variables below:<br \/>\n$dbhost = &#8216;localhost&#8217;; \/\/ Server address of your MySQL Server<br \/>\n$dbuser = &#8216;db_username&#8217;; \/\/ Username to access MySQL database<br \/>\n$dbpass = &#8216;db_password&#8217;; \/\/ Password to access MySQL database<br \/>\n$dbname = &#8216;db_name&#8217;; \/\/ Database Name<\/p>\n<p>\/\/ Options You May Optionally Configure<\/p>\n<p>$use_gzip = &#8220;no&#8221;; \/\/ Set to No if you don&#8217;t want the files sent in .gz format<br \/>\n$remove_sql_file = &#8220;yes&#8221;; \/\/ Set this to yes if you want to remove the .sql file after gzipping. Yes is recommended.<br \/>\n$remove_gzip_file = &#8220;yes&#8221;; \/\/ Set this to yes if you want to delete the gzip file also. I recommend leaving it to &#8220;no&#8221;<\/p>\n<p>\/\/ Configure the path that this script resides on your server.<\/p>\n<p>$savepath = &#8220;\/home\/username\/wpbackup&#8221;; \/\/ Full path to this directory. Do not use trailing slash!<\/p>\n<p>$send_email_w_file = &#8220;yes&#8221;; \/\/ Do you want this database backup sent to your email? Fill out the next 2 lines<br \/>\n$to = &#8220;emailaddress&#8221;; \/\/ Who to send the emails to<br \/>\n$from = &#8220;emailaddress&#8221;; \/\/ Who should the emails be sent from?<br \/>\n$senddate = date(&#8220;j F Y&#8221;);<br \/>\n$subject = &#8220;markwilson.it WordPress backup&#8221;; \/\/ Subject in the email to be sent.<br \/>\n$headers = &#8220;From: $from&#8221;;<br \/>\nif ($send_email_w_file == &#8220;yes&#8221;)<br \/>\n{<br \/>\n$message = &#8220;Attached is a MySQL dump of sitename dated $senddate.&#8221;;<br \/>\n\/\/ Brief Message.<br \/>\n}<br \/>\nelse<br \/>\n{<br \/>\n$message = &#8220;Your MySQL database has been backed up and placed in $savepath.&#8221;; \/\/ Brief Message.<br \/>\n}<\/p>\n<p>$use_ftp = &#8220;no&#8221;; \/\/ Do you want this database backup uploaded to an ftp server? Fill out the next 4 lines<br \/>\n$ftp_server = &#8220;localhost&#8221;; \/\/ FTP hostname<br \/>\n$ftp_user_name = &#8220;ftp_username&#8221;; \/\/ FTP username<br \/>\n$ftp_user_pass = &#8220;ftp_password&#8221;; \/\/ FTP password<br \/>\n$ftp_path = &#8220;\/&#8221;; \/\/ This is the path to upload on your ftp server!<\/p>\n<p>\/\/ Do not Modify below this line! It will void your warranty!<\/p>\n<p>\/\/&#8212;&#8212;&#8212;GZIP CLASS<br \/>\nclass zipfile<br \/>\n{    <\/p>\n<p>    var $datasec = array(); \/\/ array to store compressed data<br \/>\n    var $ctrl_dir = array(); \/\/ central directory<br \/>\n    var $eof_ctrl_dir = &#8220;\\x50\\x4b\\x05\\x06\\x00\\x00\\x00\\x00&#8221;; \/\/end of Central directory record<br \/>\n    var $old_offset = 0;<\/p>\n<p>    function add_dir($name)    <\/p>\n<p>    \/\/ adds &#8220;directory&#8221; to archive &#8211; do this before putting any files in directory!<br \/>\n    \/\/ $name &#8211; name of directory&#8230; like this: &#8220;path\/&#8221;<br \/>\n    \/\/ &#8230;then you can add files using add_file with names like &#8220;path\/file.txt&#8221;<br \/>\n    {<br \/>\n        $name = str_replace(&#8220;\\\\&#8221;, &#8220;\/&#8221;, $name);    <\/p>\n<p>        $fr = &#8220;\\x50\\x4b\\x03\\x04&#8221;;<br \/>\n        $fr .= &#8220;\\x0a\\x00&#8221;;    \/\/ ver needed to extract<br \/>\n        $fr .= &#8220;\\x00\\x00&#8221;;    \/\/ gen purpose bit flag<br \/>\n        $fr .= &#8220;\\x00\\x00&#8221;;    \/\/ compression method<br \/>\n        $fr .= &#8220;\\x00\\x00\\x00\\x00&#8221;; \/\/ last mod time and date<\/p>\n<p>        $fr .= pack(&#8220;V&#8221;,0); \/\/ crc32<br \/>\n        $fr .= pack(&#8220;V&#8221;,0); \/\/compressed filesize<br \/>\n        $fr .= pack(&#8220;V&#8221;,0); \/\/uncompressed filesize<br \/>\n        $fr .= pack(&#8220;v&#8221;, strlen($name) ); \/\/length of pathname<br \/>\n        $fr .= pack(&#8220;v&#8221;, 0 ); \/\/extra field length<br \/>\n        $fr .= $name;<br \/>\n        \/\/ end of &#8220;local file header&#8221; segment<\/p>\n<p>        \/\/ no &#8220;file data&#8221; segment for path<\/p>\n<p>        \/\/ &#8220;data descriptor&#8221; segment (optional but necessary if archive is not served as file)<br \/>\n        $fr .= pack(&#8220;V&#8221;,$crc); \/\/crc32<br \/>\n        $fr .= pack(&#8220;V&#8221;,$c_len); \/\/compressed filesize<br \/>\n        $fr .= pack(&#8220;V&#8221;,$unc_len); \/\/uncompressed filesize<\/p>\n<p>        \/\/ add this entry to array<br \/>\n        $this -> datasec[] = $fr;<\/p>\n<p>        $new_offset = strlen(implode(&#8220;&#8221;, $this->datasec));<\/p>\n<p>        \/\/ ext. file attributes mirrors MS-DOS directory attr byte, detailed<br \/>\n        \/\/ at http:\/\/support.microsoft.com\/suppor&#8230;s\/Q125\/0\/19.asp<\/p>\n<p>        \/\/ now add to central record<br \/>\n        $cdrec = &#8220;\\x50\\x4b\\x01\\x02&#8243;;<br \/>\n        $cdrec .=&#8221;\\x00\\x00&#8243;;    \/\/ version made by<br \/>\n        $cdrec .=&#8221;\\x0a\\x00&#8243;;    \/\/ version needed to extract<br \/>\n        $cdrec .=&#8221;\\x00\\x00&#8243;;    \/\/ gen purpose bit flag<br \/>\n        $cdrec .=&#8221;\\x00\\x00&#8243;;    \/\/ compression method<br \/>\n        $cdrec .=&#8221;\\x00\\x00\\x00\\x00&#8221;; \/\/ last mod time &#038; date<br \/>\n        $cdrec .= pack(&#8220;V&#8221;,0); \/\/ crc32<br \/>\n        $cdrec .= pack(&#8220;V&#8221;,0); \/\/compressed filesize<br \/>\n        $cdrec .= pack(&#8220;V&#8221;,0); \/\/uncompressed filesize<br \/>\n        $cdrec .= pack(&#8220;v&#8221;, strlen($name) ); \/\/length of filename<br \/>\n        $cdrec .= pack(&#8220;v&#8221;, 0 ); \/\/extra field length<br \/>\n        $cdrec .= pack(&#8220;v&#8221;, 0 ); \/\/file comment length<br \/>\n        $cdrec .= pack(&#8220;v&#8221;, 0 ); \/\/disk number start<br \/>\n        $cdrec .= pack(&#8220;v&#8221;, 0 ); \/\/internal file attributes<br \/>\n        $ext = &#8220;\\x00\\x00\\x10\\x00&#8221;;<br \/>\n        $ext = &#8220;\\xff\\xff\\xff\\xff&#8221;;<br \/>\n        $cdrec .= pack(&#8220;V&#8221;, 16 ); \/\/external file attributes  &#8211; &#8216;directory&#8217; bit set<\/p>\n<p>        $cdrec .= pack(&#8220;V&#8221;, $this -> old_offset ); \/\/relative offset of local header<br \/>\n        $this -> old_offset = $new_offset;<\/p>\n<p>        $cdrec .= $name;<br \/>\n        \/\/ optional extra field, file comment goes here<br \/>\n        \/\/ save to array<br \/>\n        $this -> ctrl_dir[] = $cdrec;    <\/p>\n<p>    }<\/p>\n<p>    function add_file($data, $name)    <\/p>\n<p>    \/\/ adds &#8220;file&#8221; to archive<br \/>\n    \/\/ $data &#8211; file contents<br \/>\n    \/\/ $name &#8211; name of file in archive. Add path if your want<\/p>\n<p>    {<br \/>\n        $name = str_replace(&#8220;\\\\&#8221;, &#8220;\/&#8221;, $name);<br \/>\n        \/\/$name = str_replace(&#8220;\\\\&#8221;, &#8220;\\\\\\\\&#8221;, $name);<\/p>\n<p>        $fr = &#8220;\\x50\\x4b\\x03\\x04&#8221;;<br \/>\n        $fr .= &#8220;\\x14\\x00&#8221;;    \/\/ ver needed to extract<br \/>\n        $fr .= &#8220;\\x00\\x00&#8221;;    \/\/ gen purpose bit flag<br \/>\n        $fr .= &#8220;\\x08\\x00&#8221;;    \/\/ compression method<br \/>\n        $fr .= &#8220;\\x00\\x00\\x00\\x00&#8221;; \/\/ last mod time and date<\/p>\n<p>        $unc_len = strlen($data);<br \/>\n        $crc = crc32($data);<br \/>\n        $zdata = gzcompress($data);<br \/>\n        $zdata = substr( substr($zdata, 0, strlen($zdata) &#8211; 4), 2); \/\/ fix crc bug<br \/>\n        $c_len = strlen($zdata);<br \/>\n        $fr .= pack(&#8220;V&#8221;,$crc); \/\/ crc32<br \/>\n        $fr .= pack(&#8220;V&#8221;,$c_len); \/\/compressed filesize<br \/>\n        $fr .= pack(&#8220;V&#8221;,$unc_len); \/\/uncompressed filesize<br \/>\n        $fr .= pack(&#8220;v&#8221;, strlen($name) ); \/\/length of filename<br \/>\n        $fr .= pack(&#8220;v&#8221;, 0 ); \/\/extra field length<br \/>\n        $fr .= $name;<br \/>\n        \/\/ end of &#8220;local file header&#8221; segment<\/p>\n<p>        \/\/ &#8220;file data&#8221; segment<br \/>\n        $fr .= $zdata;    <\/p>\n<p>        \/\/ &#8220;data descriptor&#8221; segment (optional but necessary if archive is not served as file)<br \/>\n        $fr .= pack(&#8220;V&#8221;,$crc); \/\/crc32<br \/>\n        $fr .= pack(&#8220;V&#8221;,$c_len); \/\/compressed filesize<br \/>\n        $fr .= pack(&#8220;V&#8221;,$unc_len); \/\/uncompressed filesize<\/p>\n<p>        \/\/ add this entry to array<br \/>\n        $this -> datasec[] = $fr;<\/p>\n<p>        $new_offset = strlen(implode(&#8220;&#8221;, $this->datasec));<\/p>\n<p>        \/\/ now add to central directory record<br \/>\n        $cdrec = &#8220;\\x50\\x4b\\x01\\x02&#8243;;<br \/>\n        $cdrec .=&#8221;\\x00\\x00&#8243;;    \/\/ version made by<br \/>\n        $cdrec .=&#8221;\\x14\\x00&#8243;;    \/\/ version needed to extract<br \/>\n        $cdrec .=&#8221;\\x00\\x00&#8243;;    \/\/ gen purpose bit flag<br \/>\n        $cdrec .=&#8221;\\x08\\x00&#8243;;    \/\/ compression method<br \/>\n        $cdrec .=&#8221;\\x00\\x00\\x00\\x00&#8221;; \/\/ last mod time &#038; date<br \/>\n        $cdrec .= pack(&#8220;V&#8221;,$crc); \/\/ crc32<br \/>\n        $cdrec .= pack(&#8220;V&#8221;,$c_len); \/\/compressed filesize<br \/>\n        $cdrec .= pack(&#8220;V&#8221;,$unc_len); \/\/uncompressed filesize<br \/>\n        $cdrec .= pack(&#8220;v&#8221;, strlen($name) ); \/\/length of filename<br \/>\n        $cdrec .= pack(&#8220;v&#8221;, 0 ); \/\/extra field length<br \/>\n        $cdrec .= pack(&#8220;v&#8221;, 0 ); \/\/file comment length<br \/>\n        $cdrec .= pack(&#8220;v&#8221;, 0 ); \/\/disk number start<br \/>\n        $cdrec .= pack(&#8220;v&#8221;, 0 ); \/\/internal file attributes<br \/>\n        $cdrec .= pack(&#8220;V&#8221;, 32 ); \/\/external file attributes &#8211; &#8216;archive&#8217; bit set<\/p>\n<p>        $cdrec .= pack(&#8220;V&#8221;, $this -> old_offset ); \/\/relative offset of local header<br \/>\n\/\/        echo &#8220;old offset is &#8220;.$this->old_offset.&#8221;, new offset is $new_offset<br \/>&#8220;;<br \/>\n        $this -> old_offset = $new_offset;<\/p>\n<p>        $cdrec .= $name;<br \/>\n        \/\/ optional extra field, file comment goes here<br \/>\n        \/\/ save to central directory<br \/>\n        $this -> ctrl_dir[] = $cdrec;<br \/>\n    }<\/p>\n<p>    function file() { \/\/ dump out file<br \/>\n        $data = implode(&#8220;&#8221;, $this -> datasec);<br \/>\n        $ctrldir = implode(&#8220;&#8221;, $this -> ctrl_dir);    <\/p>\n<p>        return<br \/>\n            $data.<br \/>\n            $ctrldir.<br \/>\n            $this -> eof_ctrl_dir.<br \/>\n            pack(&#8220;v&#8221;, sizeof($this -> ctrl_dir)).     \/\/ total # of entries &#8220;on this disk&#8221;<br \/>\n            pack(&#8220;v&#8221;, sizeof($this -> ctrl_dir)).     \/\/ total # of entries overall<br \/>\n            pack(&#8220;V&#8221;, strlen($ctrldir)).             \/\/ size of central dir<br \/>\n            pack(&#8220;V&#8221;, strlen($data)).                 \/\/ offset to start of central dir<br \/>\n            &#8220;\\x00\\x00&#8221;;                             \/\/ .zip file comment length<br \/>\n    }<br \/>\n}    <\/p>\n<p>\/\/&#8212;&#8212;&#8212; end class<\/p>\n<p>$date = date(&#8220;Ymd-Hi&#8221;);<br \/>\n$filename = &#8220;$savepath\/$dbname-$date.sql&#8221;;<br \/>\npassthru(&#8220;\/usr\/bin\/mysqldump &#8211;opt -h$dbhost -u$dbuser -p$dbpass $dbname >$filename&#8221;);<\/p>\n<p>if($use_gzip==&#8221;yes&#8221;){<br \/>\n    $zipfile = new zipfile();    <\/p>\n<p>    \/\/ add the subdirectory &#8230; important!<br \/>\n    $zipfile -> add_dir($savepath);<\/p>\n<p>    \/\/ add the binary data stored in the string &#8216;filedata&#8217;<br \/>\n    $file6 = fopen($filename,&#8217;rb&#8217;);<br \/>\n    $filedata = fread($file6,filesize($filename));<br \/>\n    fclose($file6);<br \/>\n    \/\/$filedata = &#8220;(read your file into $filedata)&#8221;;<br \/>\n    $zipfile -> add_file($filedata, $filename);    <\/p>\n<p>    \/\/ OR instead of doing that, you can write out the file to the loca disk like this:<br \/>\n    $filename3 = $savepath.&#8221;\/&#8221;.$dbname.&#8221;.&#8221;.$date.&#8221;_sql.tar.gz&#8221;;<br \/>\n    $fd = fopen ($filename3, &#8220;wb&#8221;);<br \/>\n    $out = fwrite ($fd, $zipfile -> file());<br \/>\n    fclose ($fd);<\/p>\n<p>    \/\/$zipline = &#8220;tar -czf &#8220;.$dbname.&#8221;.&#8221;.$date.&#8221;_sql.tar.gz &#8220;.$dbname.&#8221;-&#8220;.$date.&#8221;.sql&#8221;;<br \/>\n    \/\/echo shell_exec($zipline);<br \/>\n}<\/p>\n<p>if($use_gzip==&#8221;yes&#8221;)<br \/>\n{<br \/>\n$filename2 = $filename3;<br \/>\n}<br \/>\nelse<br \/>\n{<br \/>\n$filename2 = &#8220;$savepath\/$dbname-$date.sql&#8221;;<br \/>\n}<\/p>\n<p>if($send_email_w_file == &#8220;yes&#8221; )<br \/>\n{<br \/>\n$fileatt_type = filetype($filename2);<br \/>\n$fileatt_name = &#8220;&#8221;.$dbname.&#8221;-&#8220;.$date.&#8221;_sql&#8221;;  \/\/  change to _sql.tar.gz if gzip file<\/p>\n<p>\/\/ Read the file to be attached (&#8216;rb&#8217; = read binary)<br \/>\n$file = fopen($filename2,&#8217;rb&#8217;);<br \/>\n$data = fread($file,filesize($filename2));<br \/>\nfclose($file);<\/p>\n<p>\/\/ Generate a boundary string<br \/>\n$semi_rand = md5(time());<br \/>\n$mime_boundary = &#8220;==Multipart_Boundary_x{$semi_rand}x&#8221;;<\/p>\n<p>\/\/ Add the headers for a file attachment<br \/>\n$headers .= &#8220;\\nMIME-Version: 1.0\\n&#8221; .&#8221;Content-Type: multipart\/mixed;\\n&#8221; .&#8221; boundary=\\&#8221;{$mime_boundary}\\&#8221;&#8221;;<\/p>\n<p>\/\/ Add a multipart boundary above the plain message<br \/>\n$message = &#8220;This is a multi-part message in MIME format.\\n\\n&#8221; .&#8221;&#8211;{$mime_boundary}\\n&#8221; .&#8221;Content-Type: text\/plain; charset=\\&#8221;iso-8859-1\\&#8221;\\n&#8221; .&#8221;Content-Transfer-Encoding: 7bit\\n\\n&#8221; .<br \/>\n$message . &#8220;\\n\\n&#8221;;<\/p>\n<p>\/\/ Base64 encode the file data<br \/>\n$data = chunk_split(base64_encode($data));<\/p>\n<p>\/\/ Add file attachment to the message<br \/>\n$message .= &#8220;&#8211;{$mime_boundary}\\n&#8221; .&#8221;Content-Type: {$fileatt_type};\\n&#8221; .&#8221; name=\\&#8221;{$fileatt_name}\\&#8221;\\n&#8221; .&#8221;Content-Disposition: attachment;\\n&#8221; .&#8221; filename=\\&#8221;{$fileatt_name}\\&#8221;\\n&#8221; .&#8221;Content-Transfer-Encoding: base64\\n\\n&#8221; .<br \/>\n$data . &#8220;\\n\\n&#8221; .&#8221;&#8211;{$mime_boundary}&#8211;\\n&#8221;;<br \/>\n}<\/p>\n<p>\/\/ Send the message<br \/>\n$ok = @mail($to, $subject, $message, $headers);<br \/>\nif ($ok)<br \/>\n{<br \/>\necho &#8220;Database backup created and sent! File name $filename2&#8221;;<br \/>\n}<br \/>\nelse<br \/>\n{<br \/>\necho &#8220;Mail could not be sent. Sorry!&#8221;;<br \/>\n}<\/p>\n<p>if($use_ftp == &#8220;yes&#8221;)<br \/>\n{<br \/>\n$ftpconnect = &#8220;ncftpput -u $ftp_user_name -p $ftp_user_pass -d debsender_ftplog.log -e dbsender_ftplog2.log -a -E -V $ftp_server $ftp_path $filename2&#8221;;<br \/>\nshell_exec($ftpconnect);<br \/>\necho &#8220;<\/p>\n<h4><center>$filename2 Was created and uploaded to your FTP server!<\/center><\/h4>\n<p>&#8220;;<br \/>\n}<\/p>\n<p>if($remove_sql_file==&#8221;yes&#8221;)<br \/>\n{<br \/>\nexec(&#8220;rm -r -f $filename&#8221;);<br \/>\n}<\/p>\n<p>if($remove_gzip_file==&#8221;yes&#8221;)<br \/>\n{<br \/>\nexec(&#8220;rm -r -f $filename2&#8221;);<br \/>\n}<br \/>\n?><br \/>\n<\/dirtycode><\/p>\n<p>All you need to do is: save this on a web server somewhere; edit the variables at top of the script; and set up a cron job to run it at whatever schedule suits.<\/p>\n<p>For many people, that should be enough to ensure that their WordPress installation is safe from any catastrophe (note: no warranty is implied and I&#8217;m not responsible if things do go wrong for you).\u00c2\u00a0 For me though, I have an additional consideration as my images are not in the database&#8230; maybe that will be the subject of a future blog post.\u00c2\u00a0 In the meantime, I can sleep soundly knowing that the database behind my site is backed up regularly.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Jeff Atwood&#8217;s recent blog failure has probably served as a timely reminder to website owners across the &#8216;net &#8211; and I&#8217;m pleased to see that Jeff got his site back (some of us would be less lucky).\u00c2\u00a0 At the time, I tweeted this: &#8220;RT @edbott: Every webmaster&#8217;s nightmare: ^MW Feeling sorry for @codinghorror and thanking &hellip; <a href=\"https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Script to back up a MySQL database (e.g. for WordPress blogs)<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[],"tags":[185],"class_list":["post-1572","post","type-post","status-publish","format-standard","hentry","tag-mysql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Script to back up a MySQL database (e.g. for WordPress blogs) - markwilson.it<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Script to back up a MySQL database (e.g. for WordPress blogs) - markwilson.it\" \/>\n<meta property=\"og:description\" content=\"Jeff Atwood&#8217;s recent blog failure has probably served as a timely reminder to website owners across the &#8216;net &#8211; and I&#8217;m pleased to see that Jeff got his site back (some of us would be less lucky).\u00c2\u00a0 At the time, I tweeted this: &#8220;RT @edbott: Every webmaster&#8217;s nightmare: ^MW Feeling sorry for @codinghorror and thanking &hellip; Continue reading Script to back up a MySQL database (e.g. for WordPress blogs)\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm\" \/>\n<meta property=\"og:site_name\" content=\"markwilson.it\" \/>\n<meta property=\"article:published_time\" content=\"2009-12-21T17:58:45+00:00\" \/>\n<meta name=\"author\" content=\"Mark Wilson\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@markwilsonit\" \/>\n<meta name=\"twitter:site\" content=\"@markwilsonit\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mark Wilson\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/2009\\\/12\\\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/2009\\\/12\\\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm\"},\"author\":{\"name\":\"Mark Wilson\",\"@id\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/#\\\/schema\\\/person\\\/98f61365e7c39d6be942174b8c4de468\"},\"headline\":\"Script to back up a MySQL database (e.g. for WordPress blogs)\",\"datePublished\":\"2009-12-21T17:58:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/2009\\\/12\\\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm\"},\"wordCount\":258,\"commentCount\":8,\"publisher\":{\"@id\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/#\\\/schema\\\/person\\\/98f61365e7c39d6be942174b8c4de468\"},\"keywords\":[\"MySQL\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/2009\\\/12\\\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/2009\\\/12\\\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm\",\"url\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/2009\\\/12\\\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm\",\"name\":\"Script to back up a MySQL database (e.g. for WordPress blogs) - markwilson.it\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/#website\"},\"datePublished\":\"2009-12-21T17:58:45+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/2009\\\/12\\\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/2009\\\/12\\\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/2009\\\/12\\\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Script to back up a MySQL database (e.g. for WordPress blogs)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/\",\"name\":\"markwilson.it\",\"description\":\"get-info -class technology | write-output &gt; \\\/dev\\\/web\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/#\\\/schema\\\/person\\\/98f61365e7c39d6be942174b8c4de468\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/#\\\/schema\\\/person\\\/98f61365e7c39d6be942174b8c4de468\",\"name\":\"Mark Wilson\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/i0.wp.com\\\/www.markwilson.co.uk\\\/blog\\\/uploads\\\/image-4.png?fit=800%2C800&ssl=1\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/www.markwilson.co.uk\\\/blog\\\/uploads\\\/image-4.png?fit=800%2C800&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/www.markwilson.co.uk\\\/blog\\\/uploads\\\/image-4.png?fit=800%2C800&ssl=1\",\"width\":800,\"height\":800,\"caption\":\"Mark Wilson\"},\"logo\":{\"@id\":\"https:\\\/\\\/i0.wp.com\\\/www.markwilson.co.uk\\\/blog\\\/uploads\\\/image-4.png?fit=800%2C800&ssl=1\"},\"description\":\"A Chartered IT Professional, with recent experience in technology leadership, IT strategy and practice management roles, Mark Wilson is an Enterprise Architect in the Advisory and Management Group at risual. During a career spanning more than two decades, Mark has gained widespread recognition as an expert in his field including both industry and national press exposure. In addition to certifications from Microsoft, VMware, Red Hat, The Open Group and Axelos, Mark held a Microsoft Most Valuable Professional (MVP) award for three years and is now part of the MVP Reconnect programme. Mark is also well-known on social media and maintains an award-winning blog.\",\"sameAs\":[\"http:\\\/\\\/www.markwilson.co.uk\\\/\",\"https:\\\/\\\/www.instagram.com\\\/markwilsonuk\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/markawilson\\\/\",\"https:\\\/\\\/x.com\\\/markwilsonit\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCWHlZCoHRTocdvtrOJ2IL4A\"],\"url\":\"https:\\\/\\\/www.markwilson.co.uk\\\/blog\\\/author\\\/mark-wilson\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Script to back up a MySQL database (e.g. for WordPress blogs) - markwilson.it","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm","og_locale":"en_GB","og_type":"article","og_title":"Script to back up a MySQL database (e.g. for WordPress blogs) - markwilson.it","og_description":"Jeff Atwood&#8217;s recent blog failure has probably served as a timely reminder to website owners across the &#8216;net &#8211; and I&#8217;m pleased to see that Jeff got his site back (some of us would be less lucky).\u00c2\u00a0 At the time, I tweeted this: &#8220;RT @edbott: Every webmaster&#8217;s nightmare: ^MW Feeling sorry for @codinghorror and thanking &hellip; Continue reading Script to back up a MySQL database (e.g. for WordPress blogs)","og_url":"https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm","og_site_name":"markwilson.it","article_published_time":"2009-12-21T17:58:45+00:00","author":"Mark Wilson","twitter_card":"summary_large_image","twitter_creator":"@markwilsonit","twitter_site":"@markwilsonit","twitter_misc":{"Written by":"Mark Wilson","Estimated reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm#article","isPartOf":{"@id":"https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm"},"author":{"name":"Mark Wilson","@id":"https:\/\/www.markwilson.co.uk\/blog\/#\/schema\/person\/98f61365e7c39d6be942174b8c4de468"},"headline":"Script to back up a MySQL database (e.g. for WordPress blogs)","datePublished":"2009-12-21T17:58:45+00:00","mainEntityOfPage":{"@id":"https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm"},"wordCount":258,"commentCount":8,"publisher":{"@id":"https:\/\/www.markwilson.co.uk\/blog\/#\/schema\/person\/98f61365e7c39d6be942174b8c4de468"},"keywords":["MySQL"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm","url":"https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm","name":"Script to back up a MySQL database (e.g. for WordPress blogs) - markwilson.it","isPartOf":{"@id":"https:\/\/www.markwilson.co.uk\/blog\/#website"},"datePublished":"2009-12-21T17:58:45+00:00","breadcrumb":{"@id":"https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.markwilson.co.uk\/blog\/2009\/12\/script-to-back-up-a-mysql-database-eg-for-wordpress-blogs.htm#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.markwilson.co.uk\/blog"},{"@type":"ListItem","position":2,"name":"Script to back up a MySQL database (e.g. for WordPress blogs)"}]},{"@type":"WebSite","@id":"https:\/\/www.markwilson.co.uk\/blog\/#website","url":"https:\/\/www.markwilson.co.uk\/blog\/","name":"markwilson.it","description":"get-info -class technology | write-output &gt; \/dev\/web","publisher":{"@id":"https:\/\/www.markwilson.co.uk\/blog\/#\/schema\/person\/98f61365e7c39d6be942174b8c4de468"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.markwilson.co.uk\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":["Person","Organization"],"@id":"https:\/\/www.markwilson.co.uk\/blog\/#\/schema\/person\/98f61365e7c39d6be942174b8c4de468","name":"Mark Wilson","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/i0.wp.com\/www.markwilson.co.uk\/blog\/uploads\/image-4.png?fit=800%2C800&ssl=1","url":"https:\/\/i0.wp.com\/www.markwilson.co.uk\/blog\/uploads\/image-4.png?fit=800%2C800&ssl=1","contentUrl":"https:\/\/i0.wp.com\/www.markwilson.co.uk\/blog\/uploads\/image-4.png?fit=800%2C800&ssl=1","width":800,"height":800,"caption":"Mark Wilson"},"logo":{"@id":"https:\/\/i0.wp.com\/www.markwilson.co.uk\/blog\/uploads\/image-4.png?fit=800%2C800&ssl=1"},"description":"A Chartered IT Professional, with recent experience in technology leadership, IT strategy and practice management roles, Mark Wilson is an Enterprise Architect in the Advisory and Management Group at risual. During a career spanning more than two decades, Mark has gained widespread recognition as an expert in his field including both industry and national press exposure. In addition to certifications from Microsoft, VMware, Red Hat, The Open Group and Axelos, Mark held a Microsoft Most Valuable Professional (MVP) award for three years and is now part of the MVP Reconnect programme. Mark is also well-known on social media and maintains an award-winning blog.","sameAs":["http:\/\/www.markwilson.co.uk\/","https:\/\/www.instagram.com\/markwilsonuk\/","https:\/\/www.linkedin.com\/in\/markawilson\/","https:\/\/x.com\/markwilsonit","https:\/\/www.youtube.com\/channel\/UCWHlZCoHRTocdvtrOJ2IL4A"],"url":"https:\/\/www.markwilson.co.uk\/blog\/author\/mark-wilson"}]}},"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":3003,"url":"https:\/\/www.markwilson.co.uk\/blog\/2011\/10\/rebuilding-my-site-please-excuse-the-appearance.htm","url_meta":{"origin":1572,"position":0},"title":"Rebuilding my site: please excuse the appearance","author":"Mark Wilson","date":"Friday 7 October 2011","format":false,"excerpt":"Regular readers may have noticed that this site is looking a little... different... right now. Unfortunately, my hosting provider told me last night that they had a disk failure on the server. Normally that wouldn't be a problem (that's why servers have redundant components right? Like RAID on the disks?)\u2026","rel":"","context":"In &quot;Site notices&quot;","block_context":{"text":"Site notices","link":"https:\/\/www.markwilson.co.uk\/blog\/topic\/site-notices"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1371,"url":"https:\/\/www.markwilson.co.uk\/blog\/2009\/02\/installing-wordpress-on-a-mac.htm","url_meta":{"origin":1572,"position":1},"title":"Installing WordPress on a Mac","author":"Mark Wilson","date":"Monday 23 February 2009","format":false,"excerpt":"The software platform which markwilson.it runs on is in desperate need of an updated but there is only me to make it happen (supported by ascomi) and if I make a mistake then it may take some time for me to get the site back online (time which I don't\u2026","rel":"","context":"In \"Apache\"","block_context":{"text":"Apache","link":"https:\/\/www.markwilson.co.uk\/blog\/tag\/apache"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":7083,"url":"https:\/\/www.markwilson.co.uk\/blog\/2017\/07\/synology-hyper-backup-dsm-update-failures.htm","url_meta":{"origin":1572,"position":2},"title":"Synology Hyper Backup and DSM update failures","author":"Mark Wilson","date":"Saturday 8 July 2017","format":false,"excerpt":"I have a Synology DS916+ NAS and, for the 9 months or so, I've been using it to back up my photos to Microsoft Azure. I've realised that they are being backed up in a format that's unique to Synology's Hyper Backup program, so I should probably see if there\u2026","rel":"","context":"In &quot;Technology&quot;","block_context":{"text":"Technology","link":"https:\/\/www.markwilson.co.uk\/blog\/topic\/technology"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":657,"url":"https:\/\/www.markwilson.co.uk\/blog\/2007\/01\/free-backup-software-for-mac-os-x.htm","url_meta":{"origin":1572,"position":3},"title":"Free backup software for Mac OS X","author":"Mark Wilson","date":"Wednesday 3 January 2007","format":false,"excerpt":"A couple of years ago I suffered a hard disk failure and I was very lucky to retrieve most of my data from other sources. That should have taught me to keep backups but I'm still not as good as I should be. My work laptop is hardly ever backed\u2026","rel":"","context":"In \"Useful Software\"","block_context":{"text":"Useful Software","link":"https:\/\/www.markwilson.co.uk\/blog\/tag\/useful-software"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":60,"url":"https:\/\/www.markwilson.co.uk\/blog\/2005\/02\/ibm-rescue-and-recovery-with-rapid.htm","url_meta":{"origin":1572,"position":4},"title":"IBM Rescue and Recovery with Rapid Restore","author":"Mark Wilson","date":"Friday 18 February 2005","format":false,"excerpt":"One of the technologies that I've been working with recently is IBM's Rescue and Recovery with Rapid Restore. Another of IBM's ThinkVantage technologies, this is provided free of charge with an IBM PC (and can be licensed for other OEM's PC models). In essence, Rescue and Recovery writes a backup\u2026","rel":"","context":"In \"Lenovo\"","block_context":{"text":"Lenovo","link":"https:\/\/www.markwilson.co.uk\/blog\/tag\/lenovo"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1575,"url":"https:\/\/www.markwilson.co.uk\/blog\/2010\/02\/backing-up-and-restoring-adobe-lightroom-2-x-on-a-mac.htm","url_meta":{"origin":1572,"position":5},"title":"Backing up and restoring Adobe Lightroom 2.x on a Mac","author":"Mark Wilson","date":"Thursday 25 February 2010","format":false,"excerpt":"Over the last few days, I've been rebuilding the MacBook that I use for all my digital photography (which is a pretty risky thing to do immediately before heading off on a photography workshop) and one of the things I was pretty concerned about was backing up and restoring my\u2026","rel":"","context":"In &quot;Photography&quot;","block_context":{"text":"Photography","link":"https:\/\/www.markwilson.co.uk\/blog\/topic\/photography"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.markwilson.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1572","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.markwilson.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.markwilson.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.markwilson.co.uk\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.markwilson.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=1572"}],"version-history":[{"count":0,"href":"https:\/\/www.markwilson.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1572\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.markwilson.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=1572"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.markwilson.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=1572"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.markwilson.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=1572"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}