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

Adnane Kadri

الأعضاء
  • المساهمات

    5129
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    51

كل منشورات العضو Adnane Kadri

  1. أظن أن سؤالك متشعب كثيرا , إذ أن " تعلم HTML و CSS كمطور تطبيقات أندرويد " يعتمد بالدرجة الأولى على نهجك في تطوير هاته التطبيقات . فإذا كنت تقوم بتطوير تطبيقات الـ Android بإستعمال تقنيات هجينة من مثل ReactNative أو Cordova ، فستحتاج بالطبع إلى معرفة HTML و CSS لأنها تستخدم ذلك في مضمونها . و لكن إذا كنت تقوم بالتطوير أصليًا بإستعمال Java و XML ، فأنت لن تحتاج ذلك . أما عن كونك مشترك في دورة تطوير التطبيقات بإستخدام Javascript فأظن أن معرفة بأساسيات اللغتين ستكون كافية جدا .
  2. قد أحسنت , هاته الطريقة عملية جدا . وذلك لكون هاته المعلومات معلومات وصفية . أي أنها لا يجدر أن تظهر في الصفحة و إنما لأغراض أخرى مثل تحسين محركات البحث أو تحسين الظهور . فعوضا عن طباعة HTML يقترح فلترة المحتوى و استخراج النصوص من محتوى الـ html فقط . خصوصا في حالات من مثل الحاجة إلى هذا الحقل في أغراض أخرى , مثال : وجود حقل واحد للمقالة و لوصف صفحة المقالة في جدول المقالات في قواعد البيانات . أي أن كل محتوى كالتالي : <p style="text-align:center;"> هاته فقرة تخص وصف الصفحة </p> <h2> هذا عنوان يخص وصف الصفحة أيضا</h2> يصبح : هاته فقرة تخص وصف الصفحة هذا عنوان يخص وصف الصفحة أيضا ليمكن إستيعابها في الخاصية content كالتالي : <meta name="description" content=" هاته فقرة تخص وصف الصفحة هذا عنوان يخص وصف الصفحة أيضا" > مما يعني أنه هذا لن يسبب المشكلة السابقة . يمكنك إنشاء دالة للفلترة و تحويل كل محتوى html إلى محتوى نصي بمنطق مشابه : $text = '<p style="text-align"> هاته فقرة </p> <h2> هذا عنوان </h2>'; $cleaner_input = strip_tags($text); echo $cleaner_input; وهو نفس ما اقترحته سابقا .
  3. ليكن في العلم أن محتوى الخاصية content يقبل نصا فقط , في حين أنك تقوم بتقديم محتوى HTML إليه . لاحظ : <meta name="description" content="<p style="text-align:center;"" و بسبب علامتي التنصيص المفتوحتين في : content="<p style="text-align:center;">" ^ ^ فإن المتصفح يقوم بقراءة ما يقدم له كمحتوى HTML عادي , و بطبيعة الحال فإن هذا سيؤدي إلى ظهوره في الصفحة كـ HTML عادي . يحتمل أنك تقوم بإستعمال محرر نصوص لتحرير نص الوصف عن طريق لوحة التحكم , تأكد أنك لا تقوم بذلك , و أن الحقل news_content محتوى نصي فقط و لا يحوي أية وسوم أو عناصر HTML . يمكنك كحل لهاته المشكلة إلغاء تفعيل محرر النصوص الذي تستعمله على مدخل هذا الحقل في مكان ما بلوحة التحكم أين تقوم بتحديث نص الوصف . يحتمل أيضا أنك تقوم بإستهداف حقل غير الذي تقوم بتخزين المحتوى النصي فيه . تأكد من كل من السابق و أخبرني ما إن استمرت مشكلتك بالظهور .
  4. عموما , لا توجد أي مشكلة بالشيفرة التي لديك . يحتمل أن يكون الإختلاف الذي يظهر بين ما هو الخادم المحلي و ما هو على المستضيف هو أحد التالي : عدم إحتواء قواعد البيانات الخاصة بك على أي صفوف مدرجة بجدول topics بالمعرف المدرج في رابط الصفحة كـ : ?topics=23 يعني هذا إعادة الإستعلام الذي لديك لمصفوفة فارغة . و بالتالي عدم إمكانية قراءة الخواص news_content و title من ناتج الإستعلام . يؤدي هذا بدوره إلى نتيجة مشابهة للتالي : <meta name="keywords" content=" " /> <meta name="description" content=" "> الإحتمال الاخر هو في عدم إحتواء رابط الصفحة على معامل بالإسم topics أساسا , فبدل أن تقوم بتصفح رابط الصفحة عن طريق : https://domain.dm/path/to/my_page.php?topics=22 أنت تقوم بالتصفح إليه كالتالي : https://domain.dm/path/to/my_page.php يعني هذا تجاوز الشرط : <?php if( isset($_GET['topics']) ) : ?> و كل ما يقتضيه , و المرور مباشرة إلى شطر العبارة الشرطية الاخر : <?php else : ?> <title> موقع ....... </title> <?php endif; ?> مما يؤدي إلى عدم ظهور الوصف و الكلمات المفتاحية . لتجاوز هاته المشكلة , يقترح تصدير قواعد البيانات التي لديك على الخادم المحلي و إستيرادها في خادمك المستضيف . يقترح جانبا التأكد من أن الإتصال بقواعد البيانات يتم بشكل عادي , و من أن الجدول الذي تحاول القراءة من عليه يحوي بشكل عادي صفوفا يمكن القراءة منها .
  5. لا يزال أمامك الكثير فمحتوى الدورة غزير و شامل لكل مفاهيم تطوير واجهات المستخدم . كما أن ما يقدم لا يشمل html , css و جافاسكربت فقط بل ستمتد محتويات الدورة حتى تشمل Bootstrap و sass و jQuery , سواء من الناحية النظرية أو من الناحية التطبيقية إذ يتم تطبيق كل ما يدرس عمليا , بجانب الأشياء التي يتم استذكارها أو التعمق فيها أو توضيح أغراضها أثناء التطرق لها في التطبيق العملي .
  6. مرحبا أحمد , في مسار أساسيات CSS في دورة تطوير واجهات المستخدم في الأكاديمية يتم التحدث عن أساسيات الـ css بمجملها و منطق تعاملها , ولا يتم تناول كل خاصية على حدة . و ذلك بهدف تسهيل إستذكارها للطلاب , و لجعل عملية ترتيبها و إستيعابها منطقية . فلا نجد مثلا دروسا كالتالي : الخاصية display الخاصية flex-wrap مجموعة الخواص background بل نجد دروسا ذات عناوين و محتويات دلالية , جامعة لمجموعة أفكار تضم مجموعة خواص تصب في ذات السياق , من مثل : التعامل مع الألوان . الروابط و الأصناف الزائفة . طرق العرض display modes . و هكذا .. أي أن ترتيب الدروس و تصنيفها كالتالي يجعل من إستيعابها أسهل و أكثر وضوحا . كما أن الأمور التي ذكرتها بعيدة بعض الشيء عن الأساسيات ذاتها , فهي من الأمور المتقدمة التي يتطلب التعامل معها معرفة مسبقة بـ css .. فلا يعقل مثلا أن نستوعب عمل transition أو transform دون أن نعرف الخواص التي يتخذها العنصر أثناء و بعد تحويله . في حين أن مسار أساسيات CSS يتعرض للأساسيات فقط . و لهذا فقد تم التطرق لهاته الأمور في المسارات اللاحقة لمسار أساسيات CSS في دورة تطوير واجهات المستخدم , و لذلك فقد تم تطبيقها عمليا و بشكل مكرر في كثير من المواضع اللاحقة , مثل مسار بناء صفحات هبوط أو مجموعة الفيديوهات في قسم تجاوبية الصفحة في مسار تطوير متجر إلكتروني .. و غيرها الكثير . كما يمكنك دوما الإستزادة بالإطلاع على موسوعة حسوب .
  7. لنقم بإستكمال عملك و تحقيق ذات الغرض , ثم سنأتي لطريقة الأجاكس بعد ذلك : في ملف العرض display_items.php : نقوم بإستعمال حقل من نوع radio بدلا عن checkbox كونه عملي أكثر , و لنتأكد من إعطاء كامل الحقول ذات الإسم و ذلك كالتالي : <?php foreach ($category_data->result_array() as $row) { ?> <label> <input name="filter_cats" type="radio" value="<?php echo $row['category_name'];?>"> <?php echo $row['category_name']?> </label> <?php } ?> لنتأكد من إعطاء كامل أسطر الجدول صنفا عاما كالتالي : item و صنفا اخر خاصا كالتالي : item_[category_name] ليصبح : foreach($result as $row): echo "<tr class='item item_".$row->category_name."'>"; ثم لنقم بإضافة التفاعلية التالية : $("input[type='radio']").change(function() { if(this.checked) { let target = $(this).val(); $('.item').hide(); $('.item_' + target).show(); } }); يلخص هذا الطريقة الأولى . هاته الطريقة عملية و بسيطة في حالة محدودية المنتجات لديك , و لكن إن كنت مضطرا لإستعمال AJAX فسنلجأ لإستعمال الطريقة الثانية : و لكن هاته الطريقة أيضا غير عملية كونك لا تقوم بفصل جدول العناصر عن جدول الفئات , بل تضيف عمودا خاصا لإسم الفئة داخل جدول العناصر , و في هاته الحالة لن يمكنك الإستعلام من جدول منفصل بل من ذات الجدول الذي تريد جلب العناصر منه . و يجعل هذا العملية غير منطقية و غير عملية . فلا يوجد داع من : الإستعلام مرة أولى من الجدول tbl_items لقراءة أسماء الفئات . الإستعلام مرة ثانية من الجدول tbl_items لقراءة المنتجات الحاملة لإسم فئة معين . و بالتالي فإن أفضل حل هو ما تم إعتماده في الطريقة الأولى . خصوصا و أن المسار , ملف العرض و المتحكم يخصون المنتجات .
  8. في الغالب و بشكل عام , يعني هذا الخطأ أنه قد تم حظر عنوان IP الذي تتصل منه بواسطة إحدى خدمات الأمان للخادم الذي ترسل إليه طلبات الـ Http . و ليس المقصود بحظر عنوان IP الخاص بك حظره هو ذاته بالضرورة , بل قد يكون الحظر شمل عناوين ذات البلد مثلا . مثال : إذا كنت تتصل من شبكة مشتركة ، تكون فيها البنية التحتية للإنترنت أقل تطورًا ، فإن عناوين IP نادرة (من المرجح أن يشاركها الكثير من الأشخاص) ، فهذا يمكن أن يزيد من احتمالية رؤية هذا الخطأ . في هاته الحالة ، كإقتراح على ما يمكنك فعله هو محاولة الاتصال من شبكة أخرى مؤقتًا . أما و بشكل خاص , فستحتاج البحث في توثيق الواجهة البرمجية التي تتصل بها على دلالية كود الخطأ 1003 و إصلاح المشكلة بعد تحديدها , فقد يحتمل مثلا أن بيانات المصادقة التي تستعملها قد استهلكت .
  9. في الحقيقة , هذا ما تم وصفه في التعليق السابق . و قد تم تجزئته إلى إحتمالين : في حالة محدودية العناصر المنتمية للفئات : أين تم تفضيل عرض كل المحتوى بالصفحة و التلاعب بإظهاره و إخفاءه بحسب التفاعل مع مربعات التحقق . في حالة كثرتها : أين تم تأويل العمل بالأجاكس لعرض الفئات فقط , و إرسال طلبات الأجاكس عند التحقق من المربعات لجلب بيانات معينة تخص الفئة المحدد مربع تحققها . لاحظ تماثل منطق المثالين مع مطلوبك تماما : المثال 1 : المثال 2 : لا يقترح أن يكون طلب الأجاكس من النوع POST , فهذا الأخير موجود خصيصا لإرسال بيانات من الواجهة الأمامية للخلفية على عكس GET الذي هو موجود لعكسها . أظن أن أفضل و أقصر طريق هي ما تم وصفها سابقا , فنحن لا نقوم بإرسال أية بيانات للواجهة الخلفية . على عكس ذلك نحن نقوم بتمرير ما نحتاج في عنوان الـ URL الخاص بنا مباشرة . وهو نفس المتبع في الفيديو , على أن صاحب الفيديو يعتمد تخصيص الفلتر و إضافة مميزات أخرى بجانب غرضه الأساسي , و بالطبع يمكنك ذلك فالعملية عملية تطوير إبتداءا من فكرة صغيرة و بدائية.
  10. في الحقيقة , في لينكس لا يوجد ما يعرف بـ "إسم روت " . فـ kali@kali مثلا يجزء إلى : kali ما قابل الرمز @ معبرة عن اسم المستخدم الحالي , في الغالب يكون هو ذاته المستخدم الـ root . و : kali الأخرى ما بعد الرمز @ معبرة عن اسم المستضيف أو الجهاز . على سبيل المثال : ali@ali-lap يمكنك طباعة كل منهما بإستعمال الأمرين التاليين : whoami و : hostname تغيير إسم المستضيف يمكنك ذلك عن طريق التعديل على ملفي hostname و hosts داخل /etc بإرفاق إسم المستضيف الجديد مكان الإسم القديم . يمكنك إستعمال الأمرين التاليين لتعديلهما : sudo nano /etc/hostname sudo nano /etc/hosts سنحتاج بعد ذلك إعادة تشغيل النظام لإلتقاط هاته التحديثات : sudo reboot تغيير اسم المستخدم يتطلب هذا التأكد من أن المستخدم المراد تغيير اسمه غير مسجل للدخول حاليا , أي أن مستخدما اخر هو من يمكنه تغييره و ليس هو ذاته . و عليه سيمكنك إتباع أحد الحلين : إنشاء المستخدم باسم ali , حذف kali تماما . إنشاء مستخدم مؤقت و ليكن tempUser , و تسجيل الخروج كـ kali و تسجيله كـ tempUser . و أخيرا تغيير اسم مستخدم kali و حذف tempUser . يمكنك تغيير إسم مستخدم عن طريق مستخدم اخر كالتالي : sudo usermod -l new-name old-name كما يمكنك حذف مستخدم كالتالي : sudo userdel user-name و أخيرا إضافة مستخدم عن طريق الأمر : sudo useradd user-name كما يمكنك التبديل بين الجلسات عن طريق طباعة الأمر : su -targetUsername و طباعة كلمة المرور في حالة ظهورها .
  11. و عليكم السلام و رحمة الله . أظن أنك تقصد فلترة بيانات معينة بحسب الفئات التي تنتمي لها إعتبارا لهاته العلاقة . مثال : فلترة المنتجات بحسب الفئات التي تنتمي لها . لنقم بتجزئة الأمر إلى فكرتين : بيانات محدودة في حالة محدودية الفئات لديك يمكنك الإستغناء عن AJAX تماما و طباعة كامل الفئات مع كامل البيانات , و التعامل مع إخفاء بيانات الفئة الواحدة عن طريق أصناف CSS عادية و بعض الجافاسكربت . سيمكن ذلك كالتالي : في ملف المتحكم : جلب كامل الفئات و تمريرها إلى ملف العرض . public function index(){ $query = $this->db->get('categories'); $data['categories'] = $query->result(); $query = $this->db->get('products'); $data['products'] = $query->result(); $this->load->view('categories_view' ,$data); } في ملف العرض , عرض كامل الفئات : <?php foreach($categories as $c):?> <div> <label for="cat_<?php echo $c['id']; ?>"> <?php echo $c['name']; ?> </label> <input type="checkbox" id="cat_<?php echo $c['id']; ?>" value="<?php echo $c['id']; ?>"> </div> <?php endforeach;?> مرفقة بكامل المنتجات : <?php foreach($products as $p):?> <div class="product c_<?php echo $p['category_id']; ?>"> <h2><?php echo $p['name']; ?></h2> </div> <?php endforeach;?> ثم لنقم بإضافة التفاعلية التي تقوم بعمل التالي : عند تحديد أي مربع تحقق يتم تخزين قيمته و تحديدها . يتم إخفاء كامل المنتجات . يتم إظهار تلك التي تمتلك صنفا كالتالي : [c_[category_id . مثال عملي : عند تحديد مربع تحقق الفئة بالعنوان "ملابس رجال" يتم تخزين القيمة 5 و تحديدها . يتم إخفاء كامل المنتجات . يتم إظهار تلك التي تمتلك صنفا كالتالي : c_5 . ستفي الشيفرة التالية بذات الغرض : $("input[type='checkbox']").change(function() { if(this.checked) { let target_id = $(this).val(); $('product_container').hide(); $('c_' + target_id).show(); } }); بيانات غير محدودة سنضطر في هذا إلى إخفاء كامل العناصر (المنتجات مثلا) , و إظهار كامل الفئات : لنقم بتغيير محتوى ملف المتحكم كالتالي : public function index(){ $query = $this->db->get('categories'); $data['categories'] = $query->result(); $this->load->view('categories_view' ,$data); } public function get_products_of_category(){ $c_id = $this->input->get('category_id'); $query = $this->db->get('products')->where('category_id' ,$c_id); return $query->result(); } على أن يحتوي ملف العرض الهيكلية التالية : <?php foreach($categories as $c):?> <div> <label for="cat_<?php echo $c['id']; ?>"> <?php echo $c['name']; ?> </label> <input type="checkbox" id="cat_<?php echo $c['id']; ?>" value="<?php echo $c['id']; ?>"> </div> <?php endforeach;?> <div id="products_container" ></div> سنحتاج الان تعديل التفاعلية لتصبح كالتالي : عند تحديد أي مربع تحقق يتم تخزين قيمته و تحديدها . يتم حذف أي عناصر لمنتجات تظهر . يتم إرفاق طلبية AJAX لجلب بيانات المنتجات إلى عنوان URL مرفق بمعرف الفئة . مثال عملي : عند تحديد مربع تحقق الفئة بالعنوان "ملابس رجال" يتم تخزين القيمة 5 و تحديدها . يتم حذف أي عناصر لمنتجات تظهر و ذلك تجنبا لإضافة أي بيانات لا تهم الفئة الحالية . يتم إرفاق طلبية AJAX لجلب بيانات المنتجات إلى العنوان التالي : https://domain.info/categories/5/products عند نجاح الطلبية , يتم عرض كامل المنتجات التي تم جلبها داخل حاوي المنتجات . يترجمه : $("input[type='checkbox']").change(function() { if(this.checked) { let target_id = $(this).val(); $('#products_container').empty(); $.get("https://domain.info/categories/"+ target_id +"/products", function(data, status){ data.forEach(function(item){ $('#products_container').append('<h2>'+ item['title'] +'</h2>'); }); }); } }); و بالطبع سيجب تعريف المسارات اللازمة في ملف routes.php و إرفاقها بالمتحكمات و التوابع المتعلقة بها . سيمكن تخصيص العملية أكثر و جعلها عملية أكثر , كأن يتم إضافة حاو لكل منتج , و طباعة إسم المنتج بجانب غلافه و تخصيص تصميم هذا الحاو و غيرها من الأفكار ..
  12. يمكنك ذلك عن طريق تشغيل الأمر التالي مباشرة : passwd root أو : sudo passwd root سيطلب منك طباعة كلمة مرورك القديمة و الجديدة مع تكرار هاته الأخيرة للتأكيد . قم بعد ذلك بتقديم الطلب و ستظهر لك رسالة لطيفة تخبرك بنجاح تحديثها كالتالي : passwd: password updated successfully
  13. بالضبط , هذا ما تم الإشارة إليه سابقا في : أما عن المقصود بتوثيق طلبات الدفع , فهي تلك المسائلة البسيطة التي يطلب منك فيها اسم المستخدم و كلمة المرور عند تنفيذ الأمر : git push -u origin main ففي حالة فشل هاته المصادقة لن يتم رفع -يستحسن اللفظ دفع- ملفات المشروع إلى غيتهب . يرجى الإنتباه جيدا إلى الخطأ الذي يظهر و التصرف بناء عليه . يمكنك التخلص من المشكلة بإتباع الخطوات التالية : تحديث : يرجى الملاحظة جيدا أنه لا يوجد لديك أي مستودع على الرابط : https://github.com/najah18/cof.git في حين أنه يتوفر و بشكل عادي على : https://github.com/najah18/coffee.git يرجى التأكد جيدا من توفر المستودع على الرابط المضاف أولا . يمكن أن يسبب هذا ذات المشكلة .
  14. يحتمل أنك قد قمت بنسيان تنفيذ أحد الأوامر على نحو صحيح , كما أنه يلحظ سلوك مشابه في حالة الخطأ في إضافة رابط المستودع البعيد هلا تأكدت أولا من إصلاحها بتنفيذ الأمر التالي : git remote remove origin git remote add origin https://github.com/najah18/ecommerce.git git push -u origin main كما أنه مهم جدا إضافة اللاحقة git. مثلما ما هو موضح . إذ لم ينجح الأمر يرجى إعادة تنفيذ كافة الأوامر على نحو صحيح , و تتبع أي خطأ يظهر بأية مرحلة . هلا قمت بتنفيذ هاته الأوامر : git init git add . git commit -m "init commit" git push -u origin main و إخباري بأي أخطاء تظهر مع الإشارة إلى المرحلة أو الأمر الذي أظهر نص الخطأ . يحتمل أيضا أنك لم تقومي بتجاوز عملية توثيق طلب الدفع عند تنفيذ الأمر : git push -u origin main مما أظهر خطأ كالتالي مع اخر الأوامر : remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead. و هذا لأن طريقة توثيق طلبات الدفع عن طريق كلمة مرور حساب غيتهب قد تم التخلي عنها , و تم إستبدالها بتوكن للوصول يستعمل عند طلب كلمة المرور في توثيق الطلب عوضا عن كلمة سر الحساب . يمكنك إنشاء توكن كالتالي : الذهاب إلى الإعدادات Settings. // // إعدادات المطور Developer Settings . // // توكن وصول شخصي Personal Access Token . الضغط على توليد توكن Generate New Token . ملئ النموذج . الضغط على توليد توكن Generate token . نسخ التوكن الظاهر و الإحتفاظ به , و إستعماله في عملية توثيق الطلب عند تنفيذ الأمر : git push -u origin main
  15. هذا ليس خطأ و إنما رسالة تحذير بسيطة يتم إخبارك فيها أنه لا يمكنك محو مجلد , و يحدث هذا لأن بعض عناصر المصفوفتين تحوي سلاسل نصية كالتالي : " " , أي فراغ . يمكنك تجاهلها بكل حال من الأحوال كون الشيفرة قابلة للتنفيذ مرة واحدة . لا تنسى ضبط السطر التالي : $targetImages = array_diff($stored_imgs,$db_imgs); و ذلك وفق ما هو موضح سابقا :
  16. لاحظ عدم تماثل مخروجي المصفوفتين . فإما هذا : أو العكس : أن يكون مخروج مصفوفة المخزن تحوي اسم المجلد . فنتائج المصفوفة الأولى ممثلة للصور المخزنة 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); } يفترض أن يقوم هذا بحل المشكل . يمكنك دوما تتبع مخروج المصفوفتين عن طريق طباعة كل منهما كل مرة . توثيق الوظيفتين : array_filter preg_filter
  17. هلا قمت بتنفيذ الشيفرة التالية و إرفاق النتيجة ؟ // تحديد كامل مسارات الصور من قواعد البيانات من الجدول المستهدف و تخزينها في مصفوفة . $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); } سيمكن بهذا تتبع مخروج كل من المصفوفتين قبل تطبيق أية عمليات عليها .
  18. يعني هذا عدم تماثل بعض النتائج من قاعدة البيانات و الملفات , يحتمل أنك تقوم بتخزين اسم المجلد في قواعد البيانات أيضا . هلا تأكدت من أن الصور تظهر كالتالي في قاعدة البيانات : img1.jpg img2.jpg و ليس كـ : images/profile/img1.jpg images/profile/img2.jpg
  19. تقوم الشيفرة الموصوفة بحذف كل من : الصور المخزن مساراتها في قواعد البيانات و التي لا تتوفر على مسار فعلي في نظام الملفات. الصور المتوفرة في نظام الملفات و ليس لها توفر في قواعد البيانات . يمكنك استثناء الإحتمال الأول بالتخلص تماما من فكرة مزج مصفوفتي : ناتج فرق المصفوفة الاولى و الثانية . ناتج فرق المصفوفة الثانية و الأولى . وذلك عن طريق السطر المعني ليصبح كالتالي : $targetImages = array_diff($stored_imgs, $db_imgs);
  20. في الحقيقة نحن عادة لا نقوم بتخزين " الصور " ذاتها في قواعد البيانات بل نقوم بتخزين مسارات هاته الصور , و عوضا عن تخزينها في قواعد البيانات نحن نستخدم نظم التخزين و الملفات لذلك . كما أنه لا ينصح بتخزين الصور في جدول قاعدة البيانات. فهناك عيوب كثيرة جدا لهذا النهج. بحيث يتطلب تخزين بيانات الصورة في الجدول أن يقوم خادم قاعدة البيانات بمعالجة ونقل كميات هائلة من البيانات التي يمكن إنفاقها بشكل أفضل على المعالجة الأنسب لها . و من جانب اخر يمكن لخادم الملفات معالجة ملفات الصور هذه بشكل أفضل . بحيث يؤدي تخزين بيانات الصورة داخل حقل ثنائي إلى ترك هذه البيانات متاحة فقط للتطبيق الذي يقوم بدفق بيانات الصورة الأولية من وإلى هذا الحقل , و الميزة الوحيدة لهذا الأسلوب هي أنه يمكنك تأمين صورك بشكل أفضل لأنه يمكنك استخدام ميزات أمان قاعدة البيانات . طريقة بديلة وأفضل هي تخزين الصور خارج قاعدة البيانات و تخزين رابط فقط إلى ملف الصورة و ليكن تحت حقل اسمه img_path مثلا . بحيث سنحتاج فقط إلى حقل نص في جدول قاعدة البيانات لتخزين هذه المعلومات , كما أننا ستحتاج مزامنة البيانات في حقل الارتباط مع نظام الملفات الخاص بك لكي نتجنب مشاكل مثل التالي : و من السهل جدًا أيضًا استخدام هذه الطريقة لتخزين الصور مع مختلف لغات البرمجة , لأن معظمها تدعم وظائف القراءة من نظمم الملفات و إدارتها .
  21. يمكنك جعل العملية ديناميكية و منطقية أكثر كالتالي : يتم حذف الصورة القديمة لكل مستخدم قبل تغيير صورته في حالة ارساله لطلب . فلو كانت شيفرة تحديث صورة مستخدم ما كالتالي : $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); } يجب التأكد من تمليك الملف الحاوي لهاته الشيفرة الأذونات اللازمة لذلك , كما أنه يجب حذفها نهائيا بعد تنفيذها .
  22. يحتمل أن يكون ذلك بسبب عدم تحديث ملفات التطبيق المؤقتة , و ذلك في حالة توفر ملف بإسم home.blade.php في مجلد resources/views . و لذلك يرجى التأكد من توفر الملف المستهدف و إلا فستحتاجين إنشاءه , ثم سيمكنك محوها عن طريق تنفيذ الأمر التالي : php artisan config:clear php artisan cache:clear فمسارات التطبيق المحددة و المخزنة مؤقتا في : storage/framework/config.php قد لا تزال مضبوطة على المسار الموجود على الجهاز القديم .
  23. الأمر بالطبع ليس بالبساطة التي يظهر عليها , فلتحقيق ذلك تحتاج التكامل بين الواجهتين الأمامية و الخلفية و القراءة من قواعد البيانات بإستعلامات خاصة . و لكن عموما يمكن تحقيق فكرتك بإتباع التالي : تضمين الهاتشتاغ في رابط تشعبي خاص بصفحة عرض و فلترة الهاتشتاغات في هيكلية صفحة الـ HTML . فلترة نصوص الحقل المستهدف في الجدول المستهدف بحسب الهاتشتاغ الممرر في الرابط التشعبي . عرض النتائج الحاوية لحقول حاملة لذات الهاتشتاغ . مثال عملي في لغة الـ PHP : لنقل أننا نحتاج فلترة التدوينات التي تحتوي الهاشتاغ someHashtag اخرها . تكون الهيكلية لصفحة ما مثلا : <div class="article"> <p>some dummy text some dummy text some dummy text</p> <p>some dummy text some dummy text some dummy text</p> <a href="http://my_domain.dm/path/to/filter_tags?tag=someHashtag"> #someHashtag </a> </div> في صفحة العرض المقدمة من الرابط المعرف في الخاصية href للعنصر a في الهكلية السابقة نحتاج عمل التالي : استخراج الهاشتاغ من الرابط بناء إستعلام قراءة من قواعد البيانات إنطلاقا من المستخرج عرض النتائج يترجم ذلك الشيفرة التالية : if(isset($_GET['tag']) && $_GET['hashtag'] != '') { $tag = trim($_GET['tag']); $result = mysql_query("SELECT * FROM `articles` WHERE article LIKE '%$tag%' ORDER BY `id` DESC"); while($row = mysql_fetch_array($result)) { ?> <div> <?php echo $row['article']; ?> </div> <?php } } ?> كما يمكنك تخصيص العملية و إضافة تفاصيل أخرى .
×
×
  • أضف...