Eliminar los archivos no deseados y carpetas de la carpeta de destino en comparación con carpeta de origen

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

  •  04-10-2019
  •  | 
  •  

Pregunta

Estoy usando PHP y necesito algo así como la escritura a continuación:

Tengo que comparar la estructura de carpetas de dos y con referencia de la fuente de la carpeta I desea eliminar todos los archivos / carpetas presente en otra carpeta de destino que no existen en la fuente de referencia carpeta, ¿cómo podría hacerlo?

Editado:

$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
     }

   }
}

El código anterior muestra lo que hice .. Aquí Mi carpeta copy1 contiene archivos extra que carpetas copy2 por lo tanto, necesito estos archivos adicionales que desea eliminar.

Editado: A continuación se emite dadas son conjuntos de espejo original y de la diferencia de ambos ..

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
)

cuando iterate un bucle para eliminar en la matriz de todos los archivos de diferencia tiene que ser eliminado por salida como se muestra .. ¿Cómo puedo corregir esto .. el bucle para su eliminación es la siguiente.

$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);
}
¿Fue útil?

Solución

En primer lugar se necesita una lista recursiva de ambos directorios. Una función simple como esto funcionará:

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;

}

A continuación, se puede calcular su diferencia con array_diff .

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

interactuando sobre esta matriz, que será capaz de empezar a borrar archivos. Los directorios son un poco más complicado, ya que debe estar vacío en primer lugar.

// 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);
}

He probado cosas y debería estar funcionando bien ahora. Por supuesto, no tome mi palabra para ella. Asegúrese de configurar su propia prueba de seguridad antes de borrar datos reales.

Otros consejos

Para los directorios recursivos por favor utilice:

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

Puede hacer otras cosas como $ Archivo-> isDot (), o $ Archivo-> isFile (). Para más comandos de archivos con la visita SplFileInfo http://www.php.net/manual /en/class.splfileinfo.php

Gracias a todos por el valioso tiempo dado a mi trabajo, gracias especiales a Erisco por su dedicación para mi problema, Debajo de código es el código perfecto para acomplish la tarea que tenía que hacer, con un pequeño cambio en el de última Erisco editadas responder ...

$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);
}

En primer lugar hacer una scandir () de la carpeta original,
luego hacer un scandir en la carpeta espejo. Usa empezará a atravesar la matriz carpeta espejo y comprobar si ese archivo está presente en el scandir () de la carpeta original. algo como esto


$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);
     }
   }
}

Esto debería resolver su problema. tendrá que modificar el código anterior en consecuencia (incluir algunos recursividad en el código anterior para comprobar si la carpeta que está intentando eliminar está vacía o no, si no está vacío, entonces primero tendrá que eliminar todos los archivos / carpetas en ella y luego borrar la carpeta principal).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top