احذف الملفات والمجلدات غير المرغوب فيها من مجلد الوجهة بالمقارنة مع مجلد المصدر
سؤال
أنا أستخدم 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);
}
}
}
هذا يجب ان يحل مشكلتك. ستحتاج إلى تعديل الكود أعلاه وفقًا لذلك (قم بتضمين بعض العودية في الكود أعلاه للتحقق مما إذا كان المجلد الذي تحاول حذفه فارغًا أم لا ، إذا لم يكن فارغًا ، فستحتاج أولاً إلى حذف جميع الملفات/المجلدات في ذلك ثم حذف المجلد الأصل).