احذف الملفات والمجلدات غير المرغوب فيها من مجلد الوجهة بالمقارنة مع مجلد المصدر

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

  •  04-10-2019
  •  | 
  •  

سؤال

أنا أستخدم PHP وأحتاج إلى نص شيء مثل أدناه:

لا بد لي من مقارنة بنية مجلدين ومع مرجع المجلد المصدر ، أريد حذف جميع الملفات/المجلدات الموجودة في مجلد الوجهة الأخرى التي لا توجد في مجلد المصدر المرجعي ، كيف يمكنني القيام بذلك؟

تحرير:

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

   }
}

يعرض الرمز أعلاه ما فعلته .. هنا يحتوي مجلد Copy1 على ملفات إضافية من مجلدات Copy2 وبالتالي أحتاج إلى حذف هذه الملفات الإضافية.

تحرير:فيما يلي الإخراج المعطى عبارة عن صفائف من المرآة الأصلية وفرق كليهما ..

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
)

عندما أقوم بتكرار حلقة لحذفها على صفيف الفرق ، يجب حذف جميع الملفات حسب الإخراج المعروض .. كيف يمكنني تصحيح هذا .. يتم إعطاء الحلقة للحذف أدناه.

$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);
}
هل كانت مفيدة؟

المحلول

تحتاج أولاً إلى قائمة متكررة لكلا الأدلة. وظيفة بسيطة مثل هذه ستعمل:

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;

}

ثم يمكنك حساب اختلافهم مع array_diff.

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

التكرار على هذه الصفيف ، ستتمكن من بدء حذف الملفات. الدلائل أكثر صعوبة بعض الشيء لأنها يجب أن تكون فارغة أولاً.

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

لقد اختبرت الأشياء ويجب أن تعمل بشكل جيد الآن. بالطبع ، لا تأخذ كلامي لذلك. تأكد من إعداد الاختبار الآمن الخاص بك قبل حذف البيانات الحقيقية.

نصائح أخرى

للحصول على الدلائل العودية ، يرجى الاستخدام:

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

يمكنك القيام بأشياء أخرى مثل $ file-> ISDOT () أو $ file-> isFile (). لمزيد من أوامر الملفات مع زيارة splfileinfo http://www.php.net/manual/en/class.splfileinfo.php

شكرًا على كل الوقت الثمين الذي قدمه لعملي ، شكر خاص لإريسكو على تفانيه لمشكلتي ، فيما يلي الرمز هو الرمز المثالي لإلغاء المهمة التي كان من المفترض أن أفعلها ، مع القليل من التغيير في الرد الأخير لإريسكو .. .

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

أولاً ، قم بعمل الفراغ () للمجلد الأصلي ،
ثم القيام بفارق على مجلد المرآة.
ابدأ عبور مجموعة مجلد المرآة وتحقق مما إذا كان هذا الملف موجودًا في الفرد () للمجلد الأصلي. شيء من هذا القبيل


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

هذا يجب ان يحل مشكلتك. ستحتاج إلى تعديل الكود أعلاه وفقًا لذلك (قم بتضمين بعض العودية في الكود أعلاه للتحقق مما إذا كان المجلد الذي تحاول حذفه فارغًا أم لا ، إذا لم يكن فارغًا ، فستحتاج أولاً إلى حذف جميع الملفات/المجلدات في ذلك ثم حذف المجلد الأصل).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top