اذهب إلى المحتوى

السؤال

نشر

السلام عليكم ورحمة الله وبركاته

يقوم الاعضاء بتعديل صورهم الشخصية بالموقع بشكل مستمر مما يجعل الصور القديمة بلا فائدة وتشغل مساحة كبيرة

 في جدول الأعضاء يتم تخزين اسم وامتداد اخر صورة بهذا الشكل مثلا ( 234562.jpg ) هل هناك حل لحذف الصور التي ليس لها امتداد في الجدول ليتم حذفها من مجلد الصور

جربت استخدام كود كالتالي لكن يتم حذف جميع الصور

<?php
// جدول الأعضاء
$stmt = $db->prepare('SELECT * FROM accounts'); 
$stmt->execute();
$result = $stmt->get_result();
$r_accounts = $result->fetch_assoc(); 
$stmt->close();
//$r_accounts['image_profile_path']   امتداد الصورة
?>

<?php
$picture = glob('uploads/profile/*.jpg');
$picture = glob('uploads/profile/*.png');
$picture = glob('uploads/profile/*.......');
if (......)// لا اعرف ما هو الشرط
{
foreach($picture as $file)
{ 
if(is_file($file)) // تكرار 
{
unlink($file); // delete file
}
}
}
?>

ما اريدة فقط هو حذف الصور التي ليس لها اسم مخزن في القاعدة

Recommended Posts

  • 1
نشر

ستقوم بتحديد مسار المجلد الذي يتم تخزين الصور بداخله 

$directory = "../path/to/photos_directory/";

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

// جلب جميع الصور ذات صيغة محددة
$images = glob($directory . "*.jpg");

ثم تقوم باستخدام حلقة التكرار foreach بالمرور على جميع الصور و الصورة التي لا يكون لها اسم في قاعدة البيانات تقوم بحذفها 

foreach($images as $image)
{
    $name = explode('_',$image);
    $name = 'photos/' . $name[0];
    $sql = mysql_query("SELECT id FROM table WHERE photo1='$name' OR photo2='$name'");
    if(mysql_num_rows($sql) == 0)
	{
        unlink($directory . $image);
	}
}

فيكون كامل الكود 

$directory = "../path/to/photos_directory/";

// جلب جميع الصور ذات صيغة محددة
$images = glob($directory . "*.jpg");

foreach($images as $image)
{
    $name = explode('_',$image);
    $name = 'photos/' . $name[0];
    $sql = mysql_query("SELECT id FROM table WHERE photo1='$name' OR photo2='$name'");
    if(mysql_num_rows($sql) == 0)
	{
        unlink($directory . $image);
	}
}

 

  • 1
نشر

يمكنك جعل العملية ديناميكية و منطقية أكثر كالتالي : 

  • يتم حذف الصورة القديمة لكل مستخدم قبل تغيير صورته في حالة ارساله لطلب . فلو كانت شيفرة تحديث صورة مستخدم ما كالتالي : 
    $target_dir = "uploads/profile";
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
    $imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
    
    if(isset($_POST["change_pic"])) {
    
        move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file);
        
        $sql = "UPDATE users 
                       SET image_profile_path = '".$_FILES['fileToUpload']['name']."' 
                       WHERE id = '" .$targetUser. "'";
    
        $check = $conn->query($sql);
    }
     سيجب إضافة شيفرة الحذف كالتالي : 
    $target_dir = "uploads/profile";
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
    $imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
    
    $oldImgPath = "SELECT image_profile_path from users WHERE id = '".$targetUser."'";
    
    if(isset($_POST["change_pic"])) {
    
        move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file);
        
        $sql = "UPDATE users 
                       SET image_profile_path = '".$_FILES['fileToUpload']['name']."' 
                       WHERE id = '" .$targetUser. "'";
    
        $check = $conn->query($sql);
        
        if($check){
            unlink($oldImgPath);
        } 
    }

    و بالطبع يمكنك تخصيص الشيفرة أكثر , سيحل هذا مشكلة الإحتفاظ بالصور في حالة تعديلها . 

لكن سيبقى مشكل توفر صور لا فائدة منها . و لتفادي هذا المشكل يمكننا إنشاء شيفرة تنفذ مرة واحدة و تحذف بعد ذلك ( one-time excutable code ) , ستتبع الشيفرة المنطق التالي : 

  • تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة . 
  • تحديد كامل مسارات الصور داخل المجلد المستهدف و تخزينها في مصفوفة . 
  • تحديد العناصر الغير متوفرة في كلتا المصفوفتين .  
  • حذفها هاته العناصر . 

يترجم إلى : 

// تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة . 

$res = mysql_query('SELECT img_profile_path from users');
$db_imgs = [];

while($row = mysql_fetch_array($res))
{
    $db_imgs[] = $row['img_profile_path'];
}

// تحديد كامل مسارات الصور داخل المجلد المستهدف و تخزينها في مصفوفة . 
$stored_imgs = glob($targetDirectory . "*.jpg");

// تحديد العناصر الغير متوفرة في كلتا المصفوفتين .  
$targetImages = array_merge(array_diff($db_imgs, $stored_imgs), array_diff($stored_imgs, $db_imgs));


// حذفها هاته العناصر 
foreach($targetImages as $image)
{
    unlink($image);
}

يجب التأكد من تمليك الملف الحاوي لهاته الشيفرة الأذونات اللازمة لذلك , كما أنه يجب حذفها نهائيا بعد تنفيذها . 

 

  • 0
نشر

تظهر مشكلة كالتالي ويتم حذف الصورة المخزن اسمها في القاعدة ايضا

p_21247vv4v1.png

p_21242has41.png

<?php
// حذف الصور القديمة للمستخدم ولا فائدة منها
// تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة .
$sql = 'SELECT image_profile_path from accounts';
$result = mysqli_query($db,$sql);
$db_imgs = [];
while($row = mysqli_fetch_array($result))
{
$db_imgs[] = $row['image_profile_path'];
}
// تحديد كامل مسارات الصور داخل المجلد المستهدف و تخزينها في مصفوفة .
$targetDirectory = "uploads/profile/";
$stored_imgs = glob($targetDirectory . "*.jpg");
// تحديد العناصر الغير متوفرة في كلتا المصفوفتين .  
$targetImages = array_merge(array_diff($db_imgs, $stored_imgs), array_diff($stored_imgs, $db_imgs));
// حذفها هاته العناصر
foreach($targetImages as $image)
{
unlink($image);
}
?>

 

  • 0
نشر
بتاريخ 15 ساعات قال Hamada Ahmed:

تظهر مشكلة كالتالي ويتم حذف الصورة المخزن اسمها في القاعدة ايضا

p_21247vv4v1.png

p_21242has41.png


<?php
// حذف الصور القديمة للمستخدم ولا فائدة منها
// تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة .
$sql = 'SELECT image_profile_path from accounts';
$result = mysqli_query($db,$sql);
$db_imgs = [];
while($row = mysqli_fetch_array($result))
{
$db_imgs[] = $row['image_profile_path'];
}
// تحديد كامل مسارات الصور داخل المجلد المستهدف و تخزينها في مصفوفة .
$targetDirectory = "uploads/profile/";
$stored_imgs = glob($targetDirectory . "*.jpg");
// تحديد العناصر الغير متوفرة في كلتا المصفوفتين .  
$targetImages = array_merge(array_diff($db_imgs, $stored_imgs), array_diff($stored_imgs, $db_imgs));
// حذفها هاته العناصر
foreach($targetImages as $image)
{
unlink($image);
}
?>

 

تقوم الشيفرة الموصوفة بحذف كل من : 

  • الصور المخزن مساراتها في قواعد البيانات و التي لا تتوفر على مسار فعلي في نظام الملفات.
  • الصور المتوفرة في نظام الملفات و ليس لها توفر في قواعد البيانات .   

يمكنك استثناء الإحتمال الأول بالتخلص تماما من فكرة مزج مصفوفتي : 

  • ناتج فرق المصفوفة الاولى و الثانية . 
  • ناتج فرق المصفوفة الثانية  و الأولى .  

وذلك عن طريق السطر المعني ليصبح كالتالي : 

$targetImages = array_diff($stored_imgs, $db_imgs);

 

  • 0
نشر
بتاريخ 14 ساعات قال Adnane Kadri:

تقوم الشيفرة الموصوفة بحذف كل من : 

  • الصور المخزن مساراتها في قواعد البيانات و التي لا تتوفر على مسار فعلي في نظام الملفات.
  • الصور المتوفرة في نظام الملفات و ليس لها توفر في قواعد البيانات .   

يمكنك استثناء الإحتمال الأول بالتخلص تماما من فكرة مزج مصفوفتي : 

  • ناتج فرق المصفوفة الاولى و الثانية . 
  • ناتج فرق المصفوفة الثانية  و الأولى .  

وذلك عن طريق السطر المعني ليصبح كالتالي : 


$targetImages = array_diff($stored_imgs, $db_imgs);

 

قمت بذلك لكن يتم حذف الصورة من المجلد uploads/profile  بالرغم من ان الصورة لها مسار مخزن في القاعدة - المفترض ان يحذف فقط الصور التي ليس لها مسار مخزن في القاعدة ويترك باقي الصور

من فضلك الق نظرة اخرى على الكود ربما به خطأ وهو كالتالي

<?php
// حذف الصور القديمة للمستخدم ولا فائدة منها
// تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة .
$sql = 'SELECT image_profile_path from accounts';
$result = mysqli_query($db,$sql);
$db_imgs = [];
while($row = mysqli_fetch_array($result))
{
$db_imgs[] = $row['image_profile_path'];
}
// تحديد كامل مسارات الصور داخل المجلد المستهدف و تخزينها في مصفوفة .
$targetDirectory = "uploads/profile/";
$stored_imgs = glob($targetDirectory . "*.jpg");
// تحديد العناصر الغير متوفرة في كلتا المصفوفتين .  
$targetImages = array_diff($stored_imgs,$db_imgs);
// حذفها هاته العناصر
foreach($targetImages as $image)
{
unlink($image);
}
?>

 

  • 0
نشر
بتاريخ 4 ساعات قال Hamada Ahmed:

قمت بذلك لكن يتم حذف الصورة من المجلد uploads/profile  بالرغم من ان الصورة لها مسار مخزن في القاعدة - المفترض ان يحذف فقط الصور التي ليس لها مسار مخزن في القاعدة ويترك باقي الصور

يعني هذا عدم تماثل بعض النتائج من قاعدة البيانات و الملفات , يحتمل أنك تقوم بتخزين اسم المجلد في قواعد البيانات أيضا . 

هلا تأكدت من أن الصور تظهر كالتالي في قاعدة البيانات :

img1.jpg
img2.jpg

و ليس كـ : 

images/profile/img1.jpg
images/profile/img2.jpg

 

  • 0
نشر
بتاريخ 5 ساعات قال Adnane Kadri:

يعني هذا عدم تماثل بعض النتائج من قاعدة البيانات و الملفات , يحتمل أنك تقوم بتخزين اسم المجلد في قواعد البيانات أيضا . 

هلا تأكدت من أن الصور تظهر كالتالي في قاعدة البيانات :


img1.jpg
img2.jpg

و ليس كـ : 


images/profile/img1.jpg
images/profile/img2.jpg

 

الصور يتم تخزينها الاسم

والامتدادا كما بالصورة

p_2125vwq5b1.png

 

  • 0
نشر
بتاريخ 19 دقائق مضت قال Hamada Ahmed:

الصور يتم تخزينها الاسم

والامتدادا كما بالصورة

p_2125vwq5b1.png

 

هلا قمت بتنفيذ الشيفرة التالية و إرفاق النتيجة ؟ 

// تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة . 

$res = mysql_query('SELECT img_profile_path from users');
$db_imgs = [];

while($row = mysql_fetch_array($res))
{
    $db_imgs[] = $row['img_profile_path'];
}

// تحديد كامل مسارات الصور داخل المجلد المستهدف و تخزينها في مصفوفة . 
$stored_imgs = glob($targetDirectory . "*.jpg");

// تحديد العناصر الغير متوفرة في كلتا المصفوفتين .  
$targetImages = array_diff($stored_imgs, $db_imgs);


echo '<pre>';
print_r($targetImages);
echo '</pre>';


echo '<br><br><br><pre>';
print_r($db_imgs);
echo '</pre>';

die();
// حذفها هاته العناصر 
foreach($targetImages as $image)
{
    unlink($image);
}

سيمكن بهذا تتبع مخروج كل من المصفوفتين قبل تطبيق أية عمليات عليها .
 

  • 0
نشر
بتاريخ 14 ساعات قال Adnane Kadri:

هلا قمت بتنفيذ الشيفرة التالية و إرفاق النتيجة ؟ 


// تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة . 

$res = mysql_query('SELECT img_profile_path from users');
$db_imgs = [];

while($row = mysql_fetch_array($res))
{
    $db_imgs[] = $row['img_profile_path'];
}

// تحديد كامل مسارات الصور داخل المجلد المستهدف و تخزينها في مصفوفة . 
$stored_imgs = glob($targetDirectory . "*.jpg");

// تحديد العناصر الغير متوفرة في كلتا المصفوفتين .  
$targetImages = array_diff($stored_imgs, $db_imgs);


echo '<pre>';
print_r($targetImages);
echo '</pre>';


echo '<br><br><br><pre>';
print_r($db_imgs);
echo '</pre>';

die();
// حذفها هاته العناصر 
foreach($targetImages as $image)
{
    unlink($image);
}

سيمكن بهذا تتبع مخروج كل من المصفوفتين قبل تطبيق أية عمليات عليها .
 

لا يتم حذف اي من الصور من مجلد التخزين والنتيجة كالتالي

p_2126er5e11.png

p_2126e2cgv1.png

 

 

  • 1
نشر
بتاريخ 1 ساعة قال Hamada Ahmed:

لا يتم حذف اي من الصور من مجلد التخزين والنتيجة كالتالي

p_2126er5e11.png

p_2126e2cgv1.png

 

 

لاحظ عدم تماثل مخروجي المصفوفتين . فإما هذا : 

بتاريخ 22 ساعات قال Adnane Kadri:

يعني هذا عدم تماثل بعض النتائج من قاعدة البيانات و الملفات , يحتمل أنك تقوم بتخزين اسم المجلد في قواعد البيانات أيضا . 

أو العكس : 

  • أن يكون مخروج مصفوفة المخزن تحوي اسم المجلد . 

فنتائج المصفوفة الأولى ممثلة للصور المخزنة stored_imgs لا تماثل نتائج المصفوفة الثانية db_imgs. 

و لحل المشكلة سنقوم بإضافة السابقة uploads/profile/ إلى كل عناصر مصفوفة عناوين الصور في قواعد البيانات . يمكن ذلك عن طريق الوظيفة preg_filter كالتالي : 

$prefixedArray = preg_filter('/^/', 'prefix', $targetArray);

كما أننا سنحتاج فلترة نتائج كل من المصفوفتين للتخلص من وجود العناصر الفارغة لتجنب التحذيرات و الأخطاء التي تظهر , يمكن ذلك عن طريق الوظيفة array_filter كالتالي : 

$filteredArray = array_filter($nonFilteredArray);

لتصبح الشيفرة كاملة : 

// تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة . 
$res = mysql_query('SELECT img_profile_path from users');
$db_imgs = [];

while($row = mysql_fetch_array($res))
{
    $db_imgs[] = $row['img_profile_path'];
}

// إضافة سابقة
$db_imgs = preg_filter('/^/', 'uploads/profile/', $db_imgs);

// تحديد كامل مسارات الصور داخل المجلد المستهدف و تخزينها في مصفوفة . 
$stored_imgs = glob($targetDirectory . "*.jpg");

// تحديد العناصر الغير متوفرة في كلتا المصفوفتين .  
$targetImages = array_merge(array_diff($db_imgs, $stored_imgs), array_diff($stored_imgs, $db_imgs));

// فلترة العناصر الفارغة 
$targetImages = array_filter($targetImages);

// حذفها هاته العناصر 
foreach($targetImages as $image)
{
    unlink($image);
}

يفترض أن يقوم هذا بحل المشكل . 

يمكنك دوما تتبع مخروج المصفوفتين عن طريق طباعة كل منهما كل مرة . 

توثيق الوظيفتين :

  • 0
نشر
بتاريخ 52 دقائق مضت قال Adnane Kadri:

لاحظ عدم تماثل مخروجي المصفوفتين . فإما هذا : 

أو العكس : 

  • أن يكون مخروج مصفوفة المخزن تحوي اسم المجلد . 

فنتائج المصفوفة الأولى ممثلة للصور المخزنة stored_imgs لا تماثل نتائج المصفوفة الثانية db_imgs. 

و لحل المشكلة سنقوم بإضافة السابقة uploads/profile/ إلى كل عناصر مصفوفة عناوين الصور في قواعد البيانات . يمكن ذلك عن طريق الوظيفة preg_filter كالتالي : 


$prefixedArray = preg_filter('/^/', 'prefix', $targetArray);

كما أننا سنحتاج فلترة نتائج كل من المصفوفتين للتخلص من وجود العناصر الفارغة لتجنب التحذيرات و الأخطاء التي تظهر , يمكن ذلك عن طريق الوظيفة array_filter كالتالي : 


$filteredArray = array_filter($nonFilteredArray);

لتصبح الشيفرة كاملة : 


// تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة . 
$res = mysql_query('SELECT img_profile_path from users');
$db_imgs = [];

while($row = mysql_fetch_array($res))
{
    $db_imgs[] = $row['img_profile_path'];
}

// إضافة سابقة
$db_imgs = preg_filter('/^/', 'uploads/profile/', $db_imgs);

// تحديد كامل مسارات الصور داخل المجلد المستهدف و تخزينها في مصفوفة . 
$stored_imgs = glob($targetDirectory . "*.jpg");

// تحديد العناصر الغير متوفرة في كلتا المصفوفتين .  
$targetImages = array_merge(array_diff($db_imgs, $stored_imgs), array_diff($stored_imgs, $db_imgs));

// فلترة العناصر الفارغة 
$targetImages = array_filter($targetImages);

// حذفها هاته العناصر 
foreach($targetImages as $image)
{
    unlink($image);
}

يفترض أن يقوم هذا بحل المشكل . 

يمكنك دوما تتبع مخروج المصفوفتين عن طريق طباعة كل منهما كل مرة . 

توثيق الوظيفتين :

شكرا اخي الفاضل تمت بنجاح لكن تظهر رسالة خطأ ربما الامر بسيط

p_2126mq7pw1.png

  • 1
نشر
بتاريخ 11 ساعات قال Hamada Ahmed:

شكرا اخي الفاضل تمت بنجاح لكن تظهر رسالة خطأ ربما الامر بسيط

p_2126mq7pw1.png

هذا ليس خطأ و إنما رسالة تحذير بسيطة يتم إخبارك فيها أنه لا يمكنك محو مجلد , و يحدث هذا لأن بعض عناصر المصفوفتين تحوي سلاسل نصية كالتالي : "  " , أي فراغ . يمكنك تجاهلها بكل حال من الأحوال كون الشيفرة قابلة للتنفيذ مرة واحدة . 

لا تنسى ضبط السطر التالي : 

$targetImages = array_diff($stored_imgs,$db_imgs);

و ذلك وفق ما هو موضح سابقا : 

بتاريخ On 10/25/2021 at 19:49 قال Adnane Kadri:

تقوم الشيفرة الموصوفة بحذف كل من : 

  • الصور المخزن مساراتها في قواعد البيانات و التي لا تتوفر على مسار فعلي في نظام الملفات.
  • الصور المتوفرة في نظام الملفات و ليس لها توفر في قواعد البيانات .   

يمكنك استثناء الإحتمال الأول بالتخلص تماما من فكرة مزج مصفوفتي : 

  • ناتج فرق المصفوفة الاولى و الثانية . 
  • ناتج فرق المصفوفة الثانية  و الأولى .  

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...