كيف تحلها برمجياً ؟
- khashabawy
- 2014-03-02T15:43:52+00:00
لديك موضوع له id معين و فى داخل الموضوع يوجد تعليقات و إمكانية إدراج مرفقات أثناء كتابة التعليق
لا أريد إستخدام multipart لأقوم بالتحميل عبر Post
أقوم بعملية رفع المرفقات عن طريق iframe مخفى و jquery
لدى فى قاعدة البيانات جدول للمرفقات و به خانة attach_comment_id تحتوى رقم التعليق المرتبط بالمرفقات لتظهر أسفله عند عرضها
تتم عملية رفع المرفق قبل أن أضغط حفظ ال comment و بالتالى ال comment لم يأخذ بعد comment_id
هذه المشكلة كانت تواجهنى من قبل و كنت أحلها بطريقة أخرى وهى إضافة row فارغ أولاً فى قاعدة البيانات ليأخذ id و من ثم أقوم بتحويل المستخدم إلى صفحة Edit لهذا ال row مرسلاً فى العنوان id الموضوع لأستخدامه فى حفظ المرفقات و لكن ذلك فى حالة إنشاء موضوع جديد أو ما شابه , أما فى حالة التعليقات لا يمكن ذلك , فهل من حل ؟
يخطر ببالي في هذه اللحظة حل بسيط لهذه المشكلة, يمكنك ايجاد غيره اذا اعطيت المشكلة وقت أطول في التفكير
وهو قيامك بارجاع id للمرفق الذي قمت بتحميلة وحفظه في hidden field
وعند ادراجك للتعليق تقوم بارجاع قيمة id الخاصة بالتعليق وبعدها تبحث عن المرفقات عن طريق id الموجود في hidden field وتقوم بعمل update للقيمة
من ناحية اخرى اعتقد انه يمكنك عمل virtual directory للملفات التي يقوم المستخدمين برفعها ولم يتم ادراج التعليق الخاص بها حتى الان ليتم نسخة الى الملف المعني لاحقا مع انشاء text file يتضمن اسماء الملفات وال ip الخاص بكل ملف داخل virtual directory ليتم التعامل على اساسه لاحقا بعد ادراج التعليق, اعتقد ايضا ان هذه الطريقة ستحافظ على قاعدة البيانات لديك نظيفة اكثر من غيرها
هذه طريقة فكرت فيها ولكنها لم ترقنى لأنك ترفع قبل أن تسجل التعليق وبالتالى إن تراجعت عن قرار كتابة التعليق فقد رفعت ملفات على السيرفر لا فائدة لها
لأنه من البديهى أنك تكتب الرد و تضع المرفق و تضغط حفظ , هذا ما تعودنا عليه :)
HTML5 أظن , سأرى الحيل الممكنة :)
تقصد temporary directory . و لكن المشكلة التى أواجهها هنا هى نقل الموقع لسيرفر آخر و نسيان تفعيل service تنظيف محتويات المجلد و تراكم هذه الملفات لتزحم السيرفر و خاصة بعد تسليم الموقع للعميل , ولكن إلى الآن هذا هو أفضل حل ممكن
حسناً بعد رفع الملف لاتسجل اسمه في قاعدة البيانات انما يتم رفعة عن طريق السيرفر، وتحفظ اسمة والمعلومات في متغيرات او مصفوفة.
وعندما يضغط المستخدم زر حفظ تقوم بتسجيل التعليق ومن ثم تسجيل المرفق في قاعدة البيانات ! أليس حلاً ؟
فرضاً لم يقم بتسجيل التعليق , فبالتالى سيكون رفعنا ملفات على السيرفر بدون إستخدام لها أليس كذلك
علاقة الملف بال php ستنتهى بعد عمل upload بال Jquery و بالتالى أى تسجيل لمتغيرات تنتهى إلا إذا كان قصدك حفظها عن طريق الجافا سكريبت
1- اعمل حقل hidden field في نموذج ارسال التعليق ضع قيمته تساوي رقم فريد لا يمكن تكراره مثل ( السنة + الشهر + اليوم + الساعة + الدقيقة + الثانية ).
2- حقل attach_comment_id بدل ان تكون قيمته تساوي رقم التعليق اجعلها تساوي الرقم الفريد في الحقل hidden field .
3- اضف حقل جديد في جدول التعليق ايضا بنفس فكرة attach_comment_id تضع فيه نفس الرقم.
وبكذا عند رفع مرفق سيتم وضع الرقم الفريد في كل ملف يتم رفعه متعلق بهذا التعليقـ ايضا عند اضافة التعليق سيتم اضافة الرقم الفريد ايضا في حقل التعليق، وبكذا تكون اوجدت علاقة مابين التعليق ومرفقاته عن طريق الرقم الفريد.
اتمنى تكون وضحت الفكرة
فرضاً لم يقم بتسجيل التعليق , فبالتالى سيكون رفعنا ملفات على السيرفر بدون إستخدام لها أليس كذلك
حل الأخ Mohammed BinOthman سليم
ولا علاقة له بما إذا كان قد تم تسجيل التعليق أو لا .. حلّه المقترح كان لربط المرفقات بالتعليق قبل إضافته للقاعدة
أما مشكلة أن الملفات سيتم رفعها على السيرفر بكل الأحوال سواء سجّل التعليق أو لا، فهذه مشكلة أخرى وحلها بطريقتين
إما أن تقوم بحذف الملفات مباشرة إذا كان ليس لها parent أو تعليق مرتبط .. مجرد إستعلام بسيط يقوم بحذف كل الملفات من السيرفر التي ليست مرتبطة بتعليق(بناء على حل الأخ محمد بن عثمان)
وإما أن تغير إسلوب رفع الملفات، بحيث تجعل عملية تحميل المرفقات تبدأ مباشرة بعد الضغط على زر إضافة التعليق وليست قبله!
أنت في سؤوالك بحثت عن حل لمشكلة وفي التعليقات تسائلت عن مشكلة أخرى مختلفة ..
لأن الحلول التى تم طرحها دارت كلها فى ذهنى قبل أن أتوجه بطرح السؤال , كنت أتوقع أن تكون الإجابه شئ لا أعلمه أو شئ جديد
فبدأت أتسائل فى التعليقات عن الجزئية التى جعلتنى أرفض هذه الحلول
معك حق، وبإعتقادي لا يوجد هناك حل لمشكلة رفع الملفات للسيرفر بدون إستخدامها إذا كنت مُصرّ على رفعها قبل أن يضغط الزائر على زر إضافة التعليق ..
وبرأيي لا تخرج الحلول عن إنه إما أن تغير طريقتك في رفع الملفات بحيث تجعلها بعد الضغط على الزر، أو أن تقوم بحذف الملفات الغير مرتبطة .. هذا حسب فهمي ..
بسيطة عند رفع المرفقات قم بإنشاء ملف txt مؤقت على السيرفر يحتوي بداخله الرقم الفريد، ثم اعمل خوارزمية وظيفتها تبحث عن الملفات المؤقته التي تجاوز وقت انشاءه 30 دقيقة مثلا ثم تاخذ الرقم الفريد الذي بداخلها وتحذف جميع الملفات المرتبطة به، اما اذا تم نشر التعليق فمباشرة يتم حذف الملف المؤقت.
انت حصرت نفسك في زاوية ضيقة بعدم استخدامك للنموذج العادي و استخدامك للـ iframe هذه حلول ليست منطقية و المنطق هو ان يتم رفع التعليق مع المرفقات في نفس الوقت وهكذا تكون حليت المشكلة من اساسها بدون تعقيد المسألة، موضوع رفع المرفقات قبل نشر الموضوع هذه تستخدم في الغالب عندما يكون الشخص مسجل في الموقع، مثل البريد الالكتروني و الفيسبوك.
انت ذكرت انك لا تستخدم multipart فكيف اذن المستخدم يرفع اكثر من ملف بدون استخدام multipart ؟؟
ايضا استغربت من موضوع ال iframe في رفع مرفقات وتعليق، اعتقد ان الموضوع لا يحتاج ل iframe !!
لو توضح بالضبط الاسلوب الي استخدمة بيكون افضل لنساعدك ولو وضعت الكود بيكون افضل.
الرفع بال iframe هو وسيلة معروفه لرفع الملفات بإستخدام jquery
اضغط على New Note ثم Attach file
أرفع الملف عملية الرفع ترجع (بضم التاء) مسارا للملف أو اسم الملف فقط ويكون مموهاً [بدون حفظ في قاعدة البيانات] إن لم تكن تفضل استخدام جدول مؤقت
ويعاد ارسال معرف المرفق مع الفورم الفورم وتتم عملية الحفظ
ثم استخدام عملية مجدولة لتنظيف الملفات غير المستخدمة و الجدول المؤقت ان كنت ستستخدمه
أخي المفروض المرفق يكون هو المتعلق بالتعليق , لأن الاساسي هو التعليق
فبالتالي لو كنت مكانك كنت , سأضع في جدول المرفقات خانة وأسميها token
وسيكون في جدول التعليقات خانة أخري وأسميها attachment_token
ويكون التعامل كالتالي
عند توليد صفحة المقال , يتم توليد قيمة عشوائية , ولتكن خليط بين ايبي المستخدم والوقت الحالي مشفر بال MD5
ويأخذ رابط الرفع متغير عن طريق ال GET وليكن إسمه token وياخذ تلك القيمة العشوائية
عند إنتهاء الرفع يسجل المرفق في قاعدة البيانات معي ال token
ويكون في ال form أيضاً متغير hidden
واسمه token عند إدخال التعليق في قاعدة البيانات , يضاف ال token هذا إلى attachment_token
بالتوفيق
نفس الفكرة عندما يكون لديك تفاصيل تسجل في الجداول غير المرفقات
انا في العادة عند ارسال الفورم اعمل طلب لرقم ID جديد، حتى لو فشل الارسال هذا الرقم لن يستخدم مرة اخرى حتى في نفس الفورم (مالم يحتفظ بالرقم طالما الفور مازال مفتوح)
اذا كان لدي وسواس قهري مثلي تجاه ارقام ال ID الضائعة، عليك ان تتغلب على هذه المشكلة :)
نفس ذات الوسواس القهرى , فرضاً لم يقم بتسجيل التعليق , فبالتالى سيكون رفعنا ملفات على السيرفر بدون إستخدام لها أليس كذلك
transactions على حسب معرفتى يتم هدم كل شئ تلقائياً إذا لم تكتمل كافة الخطوات بشكل سليم
لو كنت مكانك كنت نفذتها كالتالي (تقريبا نفس طريقة الأخ Jemooo)
أرفع الملف عملية الرفع ترجع (بضم التاء) معرف للملف كمسار الملف أو اسم الملف فقط ويكون مموهاً [بدون حفظ في قاعدة البيانات] إن لم تكن تفضل استخدام جدول مؤقت
ويعاد ارسال معرف المرفق مع الفورم الفورم وتتم عملية الحفظ
ثم استخدام عملية مجدولة لتنظيف الملفات غير المستخدمة و الجدول المؤقت ان كنت ستستخدمه
هذا الحل كذلك فكرت فيه و هو إنشاء جدول موازى للمرفقات و ليكن temp_attachments و يتم تسجيل المرفقات فيه ب Hash يتواجد فى hidden input ولكن ماذا إن توقف ال cron بعد فتره بسبب نقل السيرفر و نسيت بأمره , سيمتلئ السيرفر بمرفقات كثيره لا فائدة لها (تلك التى رفعتها و لم تستخدمها)
المشكلة أن الموقع الذى أتحدث عنه هو إصدار جديد تحت الإنشاء من موقع يعمل بالفعل و يتم رفع ملفات عليه بمعدل 1000 : 10000 ملف يومياً و لكن يعمل بنظام multipart
من الممكن عدم الاعتماد على ال id و رفع الملف بكود المستخدم ويتبعة رقم الملف المرفوع
مثال
user_code = 1111
file_name = 1111_1
فى الملف التالى ستقوم بالاستعلام عن اخر كومنت للمستخدم الذى يريد رفع الملف و تضيف علية رقم ليصبح 1111_2 و تبداء بالرفع
فى حالة انك تريد كود اكثر آمناً لكى لا يستطيع احد تخمين ملفات اخرى بناء على اسم الملف الموجود فى الكومنت يمكن استخدم بدل التسلسل التاريخ كامل من السنة اللى الميكروثانية
1403020712010001
اعتقد هذا افضل فى الفهرسة واكثر أمناً وتجنب حدوث مشكلة عدم الوصول للملفات اذا حدث اى عطل فى الجدول
المشكلة ليست فى تسمية الملف إنما فى حفظه فى قاعدة البيانات و ربطه بالتعليق , حتى إذا أردت عرض التعليق مره أخرى تعرض أسفله المرفقات المرتبطه به :)
هذه طريقة اسمها "أين اذنك يا جحا" :) الطريقة الأسهل هي ما طرحه الأعضاء هنا، ارفع الصورة بعد الضغط على الزر.
لكن حلي إضافة لما ذكره jemooo، و يبدو مشكلتك مع الحل هو رفع ملفات لا حاجة لها. و هذه حلها سهل :)
يخطر ببالي في هذه اللحظة حل بسيط لهذه المشكلة, يمكنك ايجاد غيره اذا اعطيت المشكلة وقت أطول في التفكير
وهو قيامك بارجاع id للمرفق الذي قمت بتحميلة وحفظه في hidden field
وعند ادراجك للتعليق تقوم بارجاع قيمة id الخاصة بالتعليق وبعدها تبحث عن المرفقات عن طريق id الموجود في hidden field وتقوم بعمل update للقيمة
الزيادة بسيطة، بعد رفع الملف، نفذ كود جافا سكريبت بسيط هدفه "إرسال طلب تحديث
بعد رفعي للملف، ضف الملف في جدول يحوي id المرفق و "آخر تحديث". (الجدول يحوي اسماء المرفقات التي رُفعت و لم تتم تعيينها إلى رد) بعد إتمام الرفع، تقوم الصفحة بواسطة جافاسكريبت بإرسال طلب كل مثلا دقيقتين إلى /ping/attachement_id بحيث ترسل id المرفق. عندما تستقبل الطلب، حدّث قيمة "آخر تحديث". لكن متى ما عُيّن المرفق إلى رد، احذفه من هذا الجدول.
و كل مثلا ساعة (تقليل الفترة قد يؤدي إلى رفع نسبة المصادر المستخدمة و تزويدها قد يؤدي إلى استحواذ نسبة المرفقات غير المستخدمة على حيز في القرص الصلب) يمر سكريبت معين، cron يحذف كل عنصر في الجدول الذي يحوي عناصر فيها "آخر تحديث" كان قبل 10 دقائق.
بهذه الطريقة، صحيح ستقوم برفع ملفات لا داعي لها لكن ستحذفها. و أنصحك بالتفكير مليا بتغير طريقة الرفع إلى "رفع المرفق وقت الضغط على حفظ التعليق\الرد"
سؤال يحيرنى يا رائد : هل فيسبوك و المواقع العملاقة إذا قمت برفع ملف و لم تضغط حفظ يتبع هذا الاسلوب ؟
يبدو أننى سأستخدم أسلوب آخر فى حفظ المرفقات و هو نسبها إلى الموضوع و ليس إلى الردود , بحيث يكون هناك شئ مثل أرشيف الملفات فى ويدجت جانبى فى الموضوع و يمكن الإشارة لأى ملف فى التعليق بالكلام أو بالرابط دون الحاجه لأن يكون المرفق فى التعليق نفسه
قمت بتجربة جدا سريعة، و تستطيع التأكد بنفسك. فيس بوك يرفع الملف فور اختياره أما تويتر لا يرفع الصورة إلا بعد الضغط على زي تغريد.
لا أعلم لماذا يتم رفع الصور في فيسبوك قبل النشر. ربما لها علاقة بالدراسة هذه :
.
لكن بعض مواقع النشر، ما يقوموا بفعله هو حفظ مسودة لكل شئ العضو على وشك كتابته. مثلا لا أحببت الرد على موضوع بمجموعة صور، عندما أقوم برفعها، الموقع يدمجها مع التعليق حتى لو لم ينشر. و يوفر صفحة اسمها unpublished posts\replies . إذا دخلت الصفحة، ستجد مجموعة المواضيع و الردود بالصور. إذا حذف رد أو موضوع، تنحذف معه كل ما يتعلق فيها. و هذه طريقة تستطيع فعلها، أي إذا كتب العضو رد فأن الموقع يحفظ مسودة منه بكامل ما فيه من صور و كلام. و لا تحذف الصورة إلا إذا الرد حذف من قبل العضو نفسه.
تستطيع أن تقول أن هذا مثل عمل Auto save
عن طريق عمل row جديد فى قاعدة البيانات و لكن يكون هناك قيمة فى الجدول إسمها unpublished
إذا دخل العضو للموضوع يتم إستدعاء آخر unpublished comment قام به و يمكنه حفظه و نشره
إذا لم يكن هناك unpublished comment و قام بعمل focus على textarea أو حاول رفع مرفق يتم إضافة ذلك ال row و إرجاع قيمته
إن ضغط على زر حفظ كان بها و إن لم يضغط فيتم حفظ ما قام به تلقائياً عند عمل focus out
عندما يقوم المستخدم بعمل Focus على Textarea قم بأرسال Ajax لملف PHP يضع
عندما يقوم المستخدم بعمل Focus على Textarea قم بأرسال Ajax لملف PHP يضع
$_SESSION['comstatus'] = 'write';
ثم بعدها يتم رفع الملف في حالة قام بأرفاقه يتم وضع ID الملف المرفق في
$_SESSION['attachcomid'] = $id;
في حالة ضغط على زر الحفظ فان
$_SESSION['comstatus'] = 'write';
تتغير الى
$_SESSION['comstatus'] = 'done';
ويتم تخزين ID الملف داخل التعليق مع اول عملية ريفريش له يتم عمل تحقق فان كان التعليق بحالة
$_SESSION['comstatus'] = 'write';
يتم استخراج مسار الملف من ID الذي تم تخزينه
ويتم حذف الملف
لم استطيع تعديل تعليقي السابق وايضا لم استطيع حذفه لذالك كتبت التعليق مرة اخرى
كيف تعالج مشاكل إنقطاع الإتصال > إنتهاء السيشن ؟
تعتمد الفكرة التي كتبتها على مدة بسيطة وهي مدة كتابة التعليق وخلال الضغط على حفظ او الالغاء ومتابعة التصفح
لكن لكي نعالج مشكلة انتهاء السيشن
في جدول المرفقات الخاصة بالكومنت اضف حقل اسمه isdone
وليحمل القيمة 1 او 0 فان ضغط المستخدم على حفظ يتم تحويلها الى 1
وان لم يضغط على الحفظ وانتهت السيشن
فسوف تبقى قيمتها 0
بعدها انشئ ملف يقوم بالتخلص من هذه الملفات
بامكانك ان تقوم بأستدعائه في الصفحة الرئيسية للموقع ومع كل دخول لزائر سوف يقوم بعمل
SELECT * FROM `attachcom` WHERE `isdone`='0'
بعدها قم بأستدعاء الرابط الخاص بالملف وقم بحذفه بأستخدام دالة
unlink()
وان لم ترغب بتظمين الملف في الصفحة الرئيسية
استخدم Cron Job
مجتمع لمناقشة وتبادل الخبرات حول تطوير الويب. ناقش أحدث التقنيات، اللغات، والأدوات في عالم تطوير المواقع والتطبيقات. شارك مشاريعك، اسأل عن نصائح، وتعاون مع مطورين محترفين وهواة.