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

السؤال

نشر

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

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

 في جدول الأعضاء يتم تخزين اسم وامتداد اخر صورة بهذا الشكل مثلا ( 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
نشر

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

  • يتم حذف الصورة القديمة لكل مستخدم قبل تغيير صورته في حالة ارساله لطلب . فلو كانت شيفرة تحديث صورة مستخدم ما كالتالي : 
    $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);
}

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

 

  • 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
نشر
  بتاريخ On 27‏/10‏/2021 at 06:21 قال Hamada Ahmed:

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

p_2126er5e11.png

p_2126e2cgv1.png

 

 

أظهر المزيد  

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

  بتاريخ On 26‏/10‏/2021 at 09:54 قال 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);
}

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

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

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

  • 1
نشر
  بتاريخ On 27‏/10‏/2021 at 09:27 قال Hamada Ahmed:

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

p_2126mq7pw1.png

أظهر المزيد  

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

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

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

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

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

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

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

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

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

 

  • 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
نشر
  بتاريخ On 25‏/10‏/2021 at 18:12 قال 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
نشر
  بتاريخ On 25‏/10‏/2021 at 18:49 قال 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
نشر
  بتاريخ On 26‏/10‏/2021 at 05:03 قال Hamada Ahmed:

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

أظهر المزيد  

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

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

img1.jpg
img2.jpg

و ليس كـ : 

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

 

  • 0
نشر
  بتاريخ On 26‏/10‏/2021 at 09:54 قال Adnane Kadri:

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

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

img1.jpg
img2.jpg

و ليس كـ : 

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

 

أظهر المزيد  

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

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

p_2125vwq5b1.png

 

  • 0
نشر
  بتاريخ On 26‏/10‏/2021 at 15:12 قال 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
نشر
  بتاريخ On 26‏/10‏/2021 at 15:34 قال 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

 

 

  • 0
نشر
  بتاريخ On 27‏/10‏/2021 at 08:32 قال 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

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...