Database backup with php

Hello,

Database backup with php is easy to use from the website administration panel.
My backup code below works fine
But I want to add a feature
If the column type is “DEFAULT NULL” and the content is empty I want it to add NULL

if ( strlen($row[$j])>0 ){
                    $return .= "'" . $row[$j] . "'";
                } else {
                    $return .= "NULL";
                }

I am using the code as above in the data backup section but it is adding NULL to all empty fields.
This causes NULL in fields that are not “DEFAULT NULL”

How can I check if the column is “DEFAULT NULL” in the above code?

$return .= 'DROP TABLE IF EXISTS '.$table.';';

$pstm2 = $db->query('SHOW CREATE TABLE '.$table);
$row2 = $pstm2->fetch(PDO::FETCH_NUM);
$ifnotexists = str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', $row2[1]);

$return .= "\n".$ifnotexists.";\n";
$return .= "\n--\n" ;
$return .= '-- Tablonun veri dökümü `' . $table . '`' . "\n" ;
$return .= "--\n\n" ;

    for ($i = 0; $i < $num_fields; $i++) {

        @set_time_limit(0);
        $s = 0;
        while ($row = $sutun_sayisi->fetch(PDO::FETCH_NUM)) {
        $s++;
            $return .= 'INSERT INTO `' . trim($table) . '` VALUES(';
            for ($j = 0; $j < $num_fields; $j++) {
                $row[$j] = addslashes($row[$j]);
                $row[$j] = preg_replace("/\r\n/", "\\r\\n", $row[$j]);
                if ( strlen($row[$j])>0 ){
                    $return .= "'" . $row[$j] . "'";
                } else {
                    $return .= "NULL";
                }
                if ($j < ($num_fields - 1)) {
                    $return .= ', ';
                }
            }
            $return .= ");\n";
            // Tablo verinin dökümün altına ekler
            if ( $s == ( $numrow - 0 ) ){
            $return .="\n-- --------------------------------------------------------\n";
            }
            // Okunan veriyi dosyaya yaz
            fwrite($handle, $return);
            $return=null;
}// end while
            // Tabloda veri yoksa tablo yapısını dosyaya yaz
            $satir = $sutun_sayisi->rowCount();
            if($satir == '0'){
            fwrite($handle, $return);
            $return=null;        
            }      
}//end for

I think you should not allow empty content in your database, If the column is null by default It would store the record as null.

you can check if the column is null or not by querying the information_schema database

$stmt = $pdo->query("SELECT column_name, is_nullable FROM information_schema.columns WHERE  table_name =  'table_name'");
$columns = $stmt->fetchAll(PDO::FETCH_ASSOC);
1 Like

Thank you very much for your help

I know little PHP.
Sorts column names alphabetically, how to sort by default?

I think I did ORDER BY ORDINAL_POSITION

I changed it as below.
I don’t know how accurate coding is, “novice coding”

$return .= 'DROP TABLE IF EXISTS '.$table.';';

$pstm2 = $db->query('SHOW CREATE TABLE '.$table);
$row2 = $pstm2->fetch(PDO::FETCH_NUM);
$ifnotexists = str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', $row2[1]);

$return .= "\n".$ifnotexists.";\n";
$return .= "\n--\n" ;
$return .= '-- Tablonun veri dökümü `' . $table . '`' . "\n" ;
$return .= "--\n\n" ;

$nullmu = $db->query("SELECT column_name, is_nullable, column_default FROM information_schema.columns WHERE table_name = '".$table."' ORDER BY ORDINAL_POSITION ");
$nul_mu = $nullmu->fetchAll(PDO::FETCH_ASSOC);

$satirlar_dizisi = $sutun_sayisi->fetchAll(PDO::FETCH_NUM);
@set_time_limit(0);
$s = 0;
foreach($satirlar_dizisi AS $satirlardizi){
    $s++;
    $return .= 'INSERT INTO `' . trim($table) . '` VALUES(';
        foreach($satirlardizi AS $key => $value){

            $default = isset($nul_mu[$key]['COLUMN_DEFAULT']) ? $nul_mu[$key]['COLUMN_DEFAULT'] : "";

            if ( strlen((string) $value)>0 ){
                $value = addslashes($value);
                $value = preg_replace("/\r\n/", "\\r\\n", $value);
            }

            if ( strlen((string) $value)>0 ){
                $return .= "'" . $value . "'";
            } elseif( $nul_mu[$key]['IS_NULLABLE'] == 'YES' ){
                $return .= "NULL";
            }else{
                $return .= "'" . $default . "'";
            }
            if ($key < ($num_fields - 1)) {
                $return .= ', ';
            }
        }
        $return .= ");\n";
        // Tablo verinin dökümün altına ekler
        if ( $s == ( $numrow - 0 ) ){
        $return .="\n-- --------------------------------------------------------\n";
        }
        // Okunan veriyi dosyaya yaz
        fwrite($handle, $return);
        $return=null;

        // Tabloda veri yoksa tablo yapısını dosyaya yaz
        $satir = $sutun_sayisi->rowCount();
        if($satir == '0'){
        fwrite($handle, $return);
        $return=null;        
        }
}

I just met Audit Trail and saw that it is a very nice feature.
My backup code above does not backup audit trail
What is additional code to my code above to include audit trail backup? what should i do?

I have edited as below because of the problem of upper and lower case characters in local and remote server, I don’t know how accurate it is.

$return .= 'DROP TABLE IF EXISTS '.$table.';';

$pstm2 = $db->query('SHOW CREATE TABLE '.$table);
$row2 = $pstm2->fetch(PDO::FETCH_NUM);
$ifnotexists = str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', $row2[1]);

$return .= "\n".$ifnotexists.";\n";
$return .= "\n--\n" ;
$return .= '-- Tablonun veri dökümü `' . $table . '`' . "\n" ;
$return .= "--\n\n" ;

$nullmu = $db->query("SELECT upper(column_name), upper(is_nullable), upper(column_default) FROM information_schema.columns WHERE table_name = '".$table."' ORDER BY ORDINAL_POSITION ");
$nul_mu = $nullmu->fetchAll(PDO::FETCH_ASSOC);

$satirlar_dizisi = $sutun_sayisi->fetchAll(PDO::FETCH_NUM);
@set_time_limit(0);
$s = 0;
foreach($satirlar_dizisi AS $satirlardizi){
    $s++;
    $return .= 'INSERT INTO `' . trim($table) . '` VALUES(';
        foreach($satirlardizi AS $key => $value){

            $default = isset($nul_mu[$key]['upper(column_default)']) ? $nul_mu[$key]['upper(column_default)'] : "";

            if ( strlen((string) $value)>0 ){
                $value = addslashes($value) ;
                $value = preg_replace("/\r\n/", "\\r\\n", $value) ;
            }

            if ( strlen((string) $value)>0 ){
                $return .= "'" . $value . "'";
            } elseif( $nul_mu[$key]['upper(is_nullable)'] == 'YES' ){
                $return .= "NULL";
            }else{
                $return .= "'" . $default . "'" ;
            }
            if ($key < ($num_fields - 1)) {
                $return .= ', ' ;
            }
        }
        $return .= ");\n";
        // Tablo verinin dökümün altına ekler
        if ( $s == ( $numrow - 0 ) ){
        $return .="\n-- --------------------------------------------------------\n";
        }
        // Okunan veriyi dosyaya yaz
        fwrite($handle, $return);
        $return=null;

        // Tabloda veri yoksa tablo yapısını dosyaya yaz
        $satir = $sutun_sayisi->rowCount();
        if($satir == '0'){
        fwrite($handle, $return);
        $return=null;        
        }
}

Also the following differ in remote and local server
same table image
image below is image from remote server, default value is NULL
Ekran görüntüsü 2022-12-19 005940

If the same table is on the local server nothing is available in the default value
Ekran görüntüsü 2022-12-19 010016

Maybe you can use var_dump() since it’s more accurate than print_r()

Yes I saw NULL text in local with var_dump()

        foreach($satirlardizi AS $key => $value){

            $default = isset($nul_mu[$key]['upper(column_default)']) ? $nul_mu[$key]['upper(column_default)'] : "";

            if ( strlen((string) $value)>0 ){
                $return .= "'" . $value . "'";
            }else{
                $return .= "'" . $default . "'" ;
            }

With the backup code above, I made a backup both locally and on the remote server.

When typing default “NULL” on remote server

Default is empty if on local server

Why does this difference arise?

I am trying to solve this problem in backup code as below

        foreach($satirlardizi AS $key => $value){

            $default = isset($nul_mu[$key]['upper(column_default)']) ? $nul_mu[$key]['upper(column_default)'] : "";

            if ( strlen((string) $value)>0 ){
                $value = addslashes($value) ;
                $value = preg_replace("/\r\n/", "\\r\\n", $value) ;
            }

            if ( strlen((string) $value)>0 ){
                $return .= "'" . $value . "'";
            } elseif( $nul_mu[$key]['upper(is_nullable)'] == 'YES' ){
                $return .= "NULL";
            }else{
                $return .= "'" . $default . "'" ;
            }
            if ($key < ($num_fields - 1)) {
                $return .= ', ' ;
            }
        }

Output with the above code
Ekran görüntüsü 2022-12-21 121155

I just met the trigger my backup code was not backing up the trigger.
I tried to do something inexperienced by trial and error, I don’t know how true it is, I ask you to tell me the mistakes.

I backed up with phpMyAdmin

I backed up with my backup code

My trigger backup code

$trigger = $db->query(" SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_SCHEMA = '".$db_name."' AND EVENT_OBJECT_TABLE = '".$table."' ");
$trigger_dizi = $trigger->fetchAll(PDO::FETCH_ASSOC);

	if(count($trigger_dizi)>0){
		$tri = 1;
		foreach($trigger_dizi AS $trigger){
		if($tri == 1){
			$return .= "--\n";
			$return .= "-- Tetikleyiciler `".$trigger['EVENT_OBJECT_TABLE']."`";
			$return .= "\n--\n";
		}
			$return .= "DROP TRIGGER IF EXISTS `".$trigger['TRIGGER_NAME']."`;\n";
			$return .= "DELIMITER $$\n";
			$return .= 'CREATE TRIGGER `'.$trigger['TRIGGER_NAME'].'` AFTER '.$trigger['EVENT_MANIPULATION'].' ON `'.$trigger['EVENT_OBJECT_TABLE'].'` FOR EACH ROW ';
			$return .= $trigger['ACTION_STATEMENT'];
			$return .= "\n$$\n";
			$return .= "DELIMITER ;\n";
		$tri++;
		}
			$return .= "COMMIT;\n\n";

Edit:
I added this code '.$trigger['EVENT_MANIPULATION'].'

I am not really that good in databases.
All I know that you can create migration files to re-create the database from scratch and there is some tool called mysqldump that might achieve what you are trying to do in order to backup the data and you can write script for it and make a CRON job.

However, your code looks very good!

Let’s wait for more advises

1 Like
Sponsor our Newsletter | Privacy Policy | Terms of Service