Eliminare i file indesiderati e cartelle da cartella di destinazione rispetto a cartella di origine

StackOverflow https://stackoverflow.com/questions/2793090

  •  04-10-2019
  •  | 
  •  

Domanda

Sto usando PHP e ho bisogno di qualcosa di script come di seguito:

  

Devo confrontare struttura di cartelle a due   e con riferimento di fonte di cartelle I   vogliono eliminare tutti i file / cartelle   presente in altre cartella di destinazione   che non esistono in sorgente di riferimento   cartella, come potrei fare questo?

     

Modificato:

$original = scan_dir_recursive('/var/www/html/copy2');
$mirror = scan_dir_recursive('/var/www/html/copy1');
function scan_dir_recursive($dir) {

  $all_paths = array();
  $new_paths = scandir($dir);

  foreach ($new_paths as $path) {
    if ($path == '.' || $path == '..') {
      continue;
    }
    $path = $dir . DIRECTORY_SEPARATOR . $path;
    if (is_dir($path)) {
      $all_paths = array_merge($all_paths, scan_dir_recursive($path));
    } else {
      $all_paths[] = $path;
    }
  }

  return $all_paths;

}
foreach($mirror as $mirr)
{
   if($mirr != '.' && $mirr != '..')
   {
     if(!in_array($mirr, $original))
     {
        unlink($mirr);
        // delete the file
     }

   }
}

Gli spettacoli di codice di cui sopra quello che ho fatto .. Qui la mia cartella Copia1 contiene altri file di cartelle COPY2 quindi ho bisogno di questi file in più per essere cancellati.

  

Modificato:   Sotto indicati si uscita sono array di originali specchio e di differenza di entrambi ..

Original Array
(
    [0] => /var/www/html/copy2/Copy (5) of New Text Document.txt
    [1] => /var/www/html/copy2/Copy of New Text Document.txt
)

Mirror Array
(
    [0] => /var/www/html/copy1/Copy (2) of New Text Document.txt
    [1] => /var/www/html/copy1/Copy (3) of New Text Document.txt
    [2] => /var/www/html/copy1/Copy (5) of New Text Document.txt
)

Difference Array
(
    [0] => /var/www/html/copy1/Copy (2) of New Text Document.txt
    [1] => /var/www/html/copy1/Copy (3) of New Text Document.txt
    [2] => /var/www/html/copy1/Copy (5) of New Text Document.txt
)

quando ho iterare un ciclo per eliminare il matrice differenza di tutti i file deve essere soppresso come per uscita visualizzata .. come posso rimediare a questo .. il circuito per la cancellazione è riportata qui sotto.

$dirs_to_delete = array();
foreach ($diff_path as $path) {
    if (is_dir($path)) {
        $dirs_to_delete[] = $path;
    } else {
        unlink($path);
    }
}

while ($dir = array_pop($dirs_to_delete)) {
    rmdir($dir);
}
È stato utile?

Soluzione

Per prima cosa è necessario un elenco ricorsivo di entrambe le directory. Una semplice funzione come questa funzionerà:

function scan_dir_recursive($dir, $rel = null) {

  $all_paths = array();
  $new_paths = scandir($dir);

  foreach ($new_paths as $path) {

    if ($path == '.' || $path == '..') {
      continue;
    }

    if ($rel === null) {
        $path_with_rel = $path;
    } else {
        $path_with_rel = $rel . DIRECTORY_SEPARATOR . $path;
    }

    $full_path = $dir . DIRECTORY_SEPARATOR . $path;
    $all_paths[] = $path_with_rel;

    if (is_dir($full_path)) {
      $all_paths = array_merge(
        $all_paths, scan_dir_recursive($full_path, $path_with_rel)
      );
    }

  }

  return $all_paths;

}

Quindi è in grado di calcolare la loro differenza con array_diff .

$diff_paths = array_diff(
    scan_dir_recursive('/foo/bar/mirror'),
    scan_dir_recursive('/qux/baz/source')
);

iterazione di questo array, si sarà in grado di iniziare l'eliminazione di file. Le directory sono un po 'più complicato, perché devono essere vuote prima.

// warning: test this code yourself before using on real data!

$dirs_to_delete = array();
foreach ($diff_paths as $path) {
    if (is_dir($path)) {
        $dirs_to_delete[] = $path;
    } else {
        unlink($path);
    }
}

while ($dir = array_pop($dirs_to_delete)) {
    rmdir($dir);
}

Ho provato cose e dovrebbe funzionare bene ora. Naturalmente, non prendere la mia parola per esso. Assicurati di configurare il proprio test di sicurezza prima di eliminare i dati reali.

Altri suggerimenti

Per le directory ricorsive Utilizzare:

$modified_directory = new RecursiveIteratorIterator(
       new RecursiveDirectoryIterator('path/to/modified'), true
);
$modified_files = array();
foreach ($modified_directory as $file)
{
    $modified_files []= $file->getPathname();
}

Si possono fare altre cose come $ file-> isDot (), o $ file-> isFile (). Per ulteriori comandi del file con visita SPLFileInfo http://www.php.net/manual /en/class.splfileinfo.php

Grazie a tutti per il prezioso tempo dato al mio lavoro, grazie speciale a Erisco per la sua dedizione per il mio problema, Sotto codice è il codice perfetto per compire il compito che dovevo fare, con un piccolo cambiamento nel Erisco della scorsa editati rispondere ...

$source = '/var/www/html/copy1';
$mirror = '/var/www/html/copy2';

function scan_dir_recursive($dir, $rel = null) {

  $all_paths = array();
  $new_paths = scandir($dir);

  foreach ($new_paths as $path) {

    if ($path == '.' || $path == '..') {
      continue;
    }

    if ($rel === null) {
        $path_with_rel = $path;
    } else {
        $path_with_rel = $rel . DIRECTORY_SEPARATOR . $path;
    }

    $full_path = $dir . DIRECTORY_SEPARATOR . $path;
    $all_paths[] = $path_with_rel;

    if (is_dir($full_path)) {
      $all_paths = array_merge(
        $all_paths, scan_dir_recursive($full_path, $path_with_rel)
      );
    }

  }

  return $all_paths;

}
$diff_paths = array_diff(
    scan_dir_recursive($mirror),
    scan_dir_recursive($source)
);



echo "<pre>Difference ";print_r($diff_paths);

$dirs_to_delete = array();
foreach ($diff_paths as $path) {
    $path = $mirror."/".$path;//added code to unlink.
    if (is_dir($path)) {

        $dirs_to_delete[] = $path;
    } else {

        if(unlink($path))
        {
            echo "File ".$path. "Deleted.";
        }
    }
}

while ($dir = array_pop($dirs_to_delete)) {
    rmdir($dir);
}

Per prima cosa fare uno scandir () della cartella originale,
poi fare uno scandir sulla cartella di specchio.
iniziare attraversando l'array cartella di specchio e verificare se tale file è presente nella scandir () della cartella originale. qualcosa di simile


$original = scandir('path/to/original/folder');
$mirror = scandir('path/to/mirror/folder');

foreach($mirror as $mirr)
{
   if($mirr != '.' && $mirr != '..')
   {
     if(in_array($mirr, $original))
     {
        // do not delete the file
     }
     else
     {
        // delete the file
        unlink($mirr);
     }
   }
}

questo dovrebbe risolvere il problema. sarà necessario modificare il codice di cui sopra di conseguenza (includere alcuni ricorsione nel codice qui sopra per verificare se la cartella che si sta tentando di eliminare è vuota o non, se non è vuota, è necessario prima eliminare tutti i file / cartelle in essa e quindi eliminare la cartella principale).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top