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

سامح أشرف

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

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

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

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

    56

إجابات الأسئلة

  1. إجابة سامح أشرف سؤال في حذف ملفات ذات امتدادت مختلفة من مجلد بالموقع كانت الإجابة المقبولة   
    يمكنك أن تقوم بتعديل الدالة globl لكي تقوم بالبحث عن كل الملفات التي لديها الصيغة jpg أو png أو gif كالتالي:
    // غير السطر التالي $stored_imgs =glob($targetDirectory."*.jpg"); // إلى هذا السطر $stored_imgs = glob($targetDirectory."*.{jpg,png,gif}", GLOB_BRACE); بهذه الطريقة سوف يتم التطبيق على كل الصور التي لديها الصيغة jpg أو png أو gif.
  2. إجابة سامح أشرف سؤال في هل يمكن بيع ملفات WORD جاهزة على موقع خمسات؟ كانت الإجابة المقبولة   
    يُمكن بيع القوالب الجاهزة في خمسات، فعند البحث عن كلمة "قالب" على سبيل المثال، ستجد خدمات تقوم ببيع قالب معين مع بعض الإضافات والمميزات المدفوعة والإختيارية مثل بيع القالب بدون حقوق أو تركيبة على أكثر من مدونة. ويمكنك أن تقوم بعمل خدمة في خمسات وسيتم مراجعتها من قِبل فريق مختص، وإن حدثت مشكلة أو كانت الخدمة مخالفة سوف يتم الرد عليك من خلال البريد الإلكتروني بكل التفاصيل وهذا الأمر مذكور في نهاية صفحة المساعدة "إضافة خدمة مميزة".
    يمكنك أيضًا أن تقوم بإعطاء المستخدم شرح بسيط عن كيفية إستخدام القالب ومميزاته في شكل كُتيب صغير أو مقطع فيديو.
    نصيحة إضافية: قُم بقراءة بعض المقالات من الأكاديمية حول إستخدام برنامج Microsoft Word، وهذا الأمر سيساعدك للغاية في تحسين القوالب التي تقوم بها وإضافة بعض المميزات إليها.
  3. إجابة سامح أشرف سؤال في لا أستطيع إدخال البيانات على github إذ يظهر الخطأ Support for password authentication was removed كانت الإجابة المقبولة   
    بداية من شهر أغسطس الماضي لم يعد تسجيل الدخول عبر Git بإستخدام كلمة المرور ممكنًا وذلك لأغراض أمنية، بدلًا من ذلك يجب أن تقوم بتوليد Access Token من حسابك في GitHub وتقوم بإضافته إلى نظام التشغيل الخاص بك، ويمكنك أن تتبع الخطوات التالية لتوليد Access Token:
    من إعدادات حسابك في GitHub أختر Developer Settings ثم أختر Personal Access Token، أو يمكنك الدخول إلى هذه الصفحة مباشرة من هنا، ثم أضغط على Generate new Token في اليمين، سيطلب منك الموقع أن تدخل كلمة المرور الخاصة بحسابك، بعد ذلك سوف يتم تحويلك إلى صفحة لإختيار ما يمكن القيام به عبر الـ Access Token هذا، أختر repo على الأقل (يمكن أن تختار ما تريده ولكن تأكد من إختيار repo أيضًا لكي تتمكن من رفع الملفات على GitHub)، وقم بإضافة اسم أو أي نص في خانة Note، ثم أضغط على Generate Token في أسفل الصفحة، سوف يظهر لك كود مشابه للتالي وعليك نسخة وحفظه في مكان آمن لأنك لن تتمكن من الحصول عليه مرة أخرى (لكن يمكنك أن تقوم بتوليد Access Token مرة أخرى بالطبع)
    ghp_sFhFsSHhTzMDreGRLjmks4Tzuzgthdvfsrta الآن يجب إضافة الكود السابق إلى نظام التشغيل الخاص بك لكي يتعرف Git عليه، وذلك من خلال لوحة التحكم Control Panel قم بفتح Credentials Manager واختر Windows Credentials ثم أبحث عن الاختيار git:https://github.com وأضغط على edit كما في الصورة:

    الآن قم بإضافة الـ access token الذ يتم توليده في الخطوة الأولى في خانة password، وتأكد من أن اسم المستخدم User Name هو اسم المستخدم الخاص بك في GitHub، ثم أضغط على Save.
    إذا لم تجد أي أختيار باسم git:https://github.com فيمكنك أن تضيفه من خلال الضغط على Add a generic credential، وأكتب البيانات التالية:
    Internet or network address:
    git:https://github.com User Name: اسم المستخدم الخاص بك في GitHub
    password: ضع الـ access token الذي لديك هنا.
    الآن يمكنك إعادة محاولة رفع المشروع الخاص بك على GitHub.
  4. إجابة سامح أشرف سؤال في كيف أقوم بتسعير منتجى كخدمة كانت الإجابة المقبولة   
    لا يمكن حساب تكلفة التطبيق بشكل صريح لأن التطبيقات تختلف في المواصفات والمميزات ولا توجد طريقة واضحة أو متبعة بشكل عام لحساب تكلفة أي مشروع، فالتكلفة تتبع نظام العرض والطلب ويمكن المساومة بين المبرمج والعميل على سعر المشروع والوقت المستغرق لإنشائه أيضًا وحتى التقنيات المستخدمه فيه، وأفضل طريقة لحساب متوسط تكلفة مشروع ميعن هي من خلال فحص سوق العمل والبحث عن مشاريع مشابهة تمت بالفعل، لمعرفة متوسط تكلفة المشروع، أما إن لم تتمكن من إيجاد مشروع مشابه فيمكنك أن تقوم بتحليل المشروع ومعرفة عدد الصفحات التقريبي فيه والأقسام في أغلب الصفحات وبالتالي سيمكنك أن تقوم بحساب تكلفة المشروع التقريبية وستستطيع تحديد الوقت الذي ستستغرقه في إنشاء هذا المشروع.
    يعتمد الأمر في البداية على العرض الذي تقدمه، ففي الغالب لا يكون العميل على دراية بالأمور التقنية مثل لغة البرمجة المستعملة في المشروع أو إطار العمل أو حتى قد لا يعرف الفرق بين واجهة المستخدم Frontend والواجهة الخلفية Backend، وبالتالي قد يكون طلب العميل هو إنشاء موقع كامل (Frontend & Backend)، ولكن طلبه لا يوضح هذا الأمر بشكل واضح، وذلك بسبب نقص الخبرة لدى العميل، وبالتالي يكون على المبرمج هنا أن يوضح هذا الأمر من بداية المشروع ويوضح للعميل ما سيحصل عليه بشكل كامل.
    أيضًا قد يكون لدى العميل تصور معين للمشروع النهائي، ولكن يمكن ان يحتوي تصوره هذا على مشاكل في بنية المشروع أو تجربة المستخدم أو حتى في تكلفة المشروع ككل، ويمكن للمبرمج في هذه الحالة أن يوضح للعميل أي الطرق أفضل بشكل بيسط لأداء مهمة معينة ولمذا يجب إستخدام تقنية معينة بدلًا من أخرى، فعلى سبيل المثال قد يرغب عميل ما إنشاء مدونة بلغة PHP ويمكن للمبرمج أن يقترح عليه أن يستخدم إطار عمل Laravel لإنشاء المشروع بشكل أسرع وأكثر آمانًا .. إلخ. وسيكون قرار العميل هو الفاصل في مثل هذه القرارات، فهذا مشروعه هو في النهاية.
    ولكي يكون العرض الذي تقدمه مناسبًا للعميل، فيجب فهم ما يريده العميل أولًا، ومحاولة عرض المميزات التي يقدمه المنتج الخاص بك مقارنة بما يريده العميل، فعلى سبيل المثال: إن كان العميل يريد إنشاء مدونة بإطار العمل Laravel، فيمكنك ان تقترح عليه المنتج الخاص بك الذي يوفر إنشاء التدوينات وتصنيفها في أقسام مع صفحة للبحث في المدونة وتحسين السيو الخاص بالموقع كذلك، بهذا الشكل يكون المنتج الخاص بك يغطي حاجة العميل، وكذلك يوفر له مميزات إضافية. قد تبدو المميزات السابقة بديهية وموجودة في أي مدونة، ولكن كما ذكرت سابقًا، فغالبًا لا يكون لدى العميل الفكرة الكاملة عن الأمور التقنية والمميزات التي يحتاجها بشكل كامل، لذلك يجب إستغلال هذا الأمر لعرض كل ما يقدمه منتجك.
    أما إن كان العكس، مثل أن يكون منتجك لا يحتوي على ميزة معينة يرغب به العميل، فيمكنك أن تعرض عليه إضافة هذه الميزة إلى منتجك وبيعه إياه -وسيكون هذا أفضل حل-، أو إستبدالها بميزة أخرى تغطي حاجته للميزة الأولى، مثل أن يرغب العميل بميزة إضافة وسوم إلى التدوينات، فتقترح عليه إستخدام الأصناف بدلًا منها مع توضيح سبب لذلك مثل أن الأصناف تكون أكثر تنظيمًا ويسهل على المستخدمين البحث فيها على سبيل المثال.
  5. إجابة سامح أشرف سؤال في خطأ في Flutter عند إسناد قائمة لأخرى The argument type 'List<dynamic>' can't be assigned to the parameter type 'List<Widget>' كانت الإجابة المقبولة   
    تحتاج إلى تحديد نوع محتويات القائمة List، وذلك عبر تحديد نوع Widget كالتالي:
    List<Widget> fafa = [ // ^^^^^^^^^ Padding( padding: const EdgeInsets.all(3.0), child: Icon( Icons.thumb_up, color: Colors.lightGreen[400], ), ), Padding( padding: const EdgeInsets.all(3.0), child: Icon( Icons.thumb_down, color: Colors.red[600], ), ), Padding( padding: const EdgeInsets.all(3.0), child: Icon( Icons.thumb_up, color: Colors.lightGreen[400], ), ), Padding( padding: const EdgeInsets.all(3.0), child: Icon( Icons.thumb_down, color: Colors.red[600], ), ), ]; يحدث هذا الأمر لأن المعامل children في الصف Row يحتاج إلى قائمة من نوع Widget بشكل إفتراضي، ويمكنك التأكد من ذلك من خلال وقوف بمؤشر الفأرة على كلمة children في محرر VS Code وسيظهر لك نوع هذا المعامل، كما في الصورة:

    ملاحظة: إن لم تقم بتحديد نوع الكائنات في القائمة، فسيكون نوع القائمة <List<dynamic بشكل إفتراضي، وهذا بالطبع مخالف لما يستقبله المعامل children
    يمكنك أيضًا أن تستخدم معامل النشر Spread Operator ( ... )، كما وضح المدرب وائل في إجابته.
  6. إجابة سامح أشرف سؤال في ما هو الأمن السبراني وكيفية تعلمه؟ كانت الإجابة المقبولة   
    الآمن السبراني هو عملية لحماية الأنظمة والأجهزة في مؤسسة ما بهدف منع الهجمات الإلكترونية عليها، حيث تحتوي هذه الأنظمة والأجهزة -المراد حمايتها- على معلومات سرية أو حساسة. وتهدف الهجمات الإلكترونية هذه إلى الوصول إلى هذه المعلومات بغية تسريبها أو تغيرها أو حتى تدميرها.
    وينقسم المن السيبراني إلى طبقات من الحماية تنتشر عبر أجهزة الكمبيوتر والشبكات والبرامج (وفي بعض الأحيان الأشخاص) التي يجب حمايتها والحفاظ عليها، ويتم الإتفاق وتقسيم هذه الطبقات حسب رغبة المؤسسة أو المنظمة وما تراه مناسبًا لها.
    بعض أنواع التهديد في الأمن السيبراني
    تصيد المعلومات Phishing Information
    ويتم في هذه العملية إرسال محتوى زائف مشابهة لمحتوى أصلي موثوق، مثل إرسال رسالة إلى بريد إلكتروني مزورة أو إرسال رابط موقع مشابهة لموقع معروف مثل Facebook على سبيل المثال، وهذا بغرض الحصول على معلومات حساسة وسرية، مثل كلمات المرور أو أرقام البطاقات الإتمانية أو أجوبة لأسئلة سرية .. إلخ، وبالطبع قد ينخدع عدد من المستخدمين في مثل هذا الإحتيال ظنًا منهم أنه هذا هو الموقع الحقيقي أو أن هذه عبارة عن رسالة رسمية موثوقة.
    البرامج الضارة Malware
    وهي برامج يتم إرسالة إلى الضحايا بأي شكل كان، وتهدف هذه البرامج إلى الوصول الكامل لجهاز الكمبيوتر والتحكم فيه عن بعد بطريقة غير مرئية، بهدف إستخراج معلومات سرية أو مراقبة صاحب الجهاز أو حتى الوصول إلى أجهزة أخرى في المؤسسة .. إلخ، وهذه البرامج الضارة يتم الكشف عنها في الغالب عن طريق طرق بسيطة مثل إستخدام برامج الحماية Anti-Virus أو من خلال طرق أكثر تعقيدًا مثل مراقبة نشاطات البرنامج وما يحاول القيام به في بيئة إفتراضية معزولة Isolated Virtual Environment .. إلخ.
    برامج الفدية الضارة Ransomware
    وهي برامج ضارة تحاول تشفير كل محتويات جهاز الكمبيوتر (أو نوع معين من الملفات)، بغرض من صاحب الجهاز من الوصول إلى هذه الملفات أو إستخدامها إلا بعد دفع مبلغ مالي (فدية) إلى صانع برنامج الفدية، وفي الغالب تتم هذه العملية عبر عملة مشفر يصعب تتبع صاحبها مثل البيتكوين أو إيثريوم Ethereum وغيرها. وفي كثير من الأحيان تفشل المنظمة (أو صاحب جهاز الكمبيوتر) من إعادة الملفات المشفرة وفك تشفيرها.
    متطلبات الأمن السيبراني
    يحتاج متخصص الأمن السيبراني إلى تعلم الكثير من المهارات التي تُمكنه من التعرف على التهديدات وكيفية مواجهتها، كما أنه بحاجة إلى مهارات التفكير بشكل تحليلي ونقدي وحل المشكلات والقدرة على العمل بشكل جيد سواء كفرد أو ضمن فريق.
    أيضًا المهارات التقنية مثل تعلم لغات البرمجة والخوارزميات وبنية البرامج والأنظمة وكيفية حمايتها من التهديدات تُعد مهارات أساسية لا غنى عنها. كما أنه بحاجة إلى القراءة عن أشهر الثغرات وكيفية عملها وإستغلالها وكيفية الحماية منها أيضًا.
  7. إجابة سامح أشرف سؤال في من أين نأتي بأفكار للتطبيقات؟ ومدة عمل تطبيق؟ كانت الإجابة المقبولة   
    "الحاجة أم الإختراع"، تنبع أغلب أفكار التطبيقات من مشاكل كانت تواجهة صانيعيها أو مشاكل تواجهة فئة معينة من المستخدمين، لذلك يمكنك أن تبحث عن المشاكل التي تواجهة فئة من المستخدمين في الوقت الحالي، ويكون ذلك عبر سؤالهم بشكل مباشر أو البحث بشكل يدوي عن هذه المشاكل من خلال تجربة التطبيقات والبرامج أو المواقع بنفسك ومحاولة إعادة إنشائها مرة اخرى مع حل المشكلات الموجودة بها بالفعل.
    حتى أن المشكلة التي تواجهك الآن (صعوبة الحصول على أفكار لمشاريع وتطبيقات) قد تُعد فكرة لمشروع جديد في حد ذاتها، وبذلك يمكنك عمل تطبيق يحتوي على أفكار لمشاريع بسيطة ويمكن للمستخدمين إضافة أفكار جديدة ليقوم أحد المبرمجين بمحاولة إنشاء هذه الفكرة، وإنتاج مشروع جديد يُفيد المستخدمين..
    أيضًا يمكنك أن تقوم بتصفح مواقع العمل الحر للحصول على أفكار لمساعدة العملاء، فعلى سبيل المثال قد تجد أن كثير من العملاء يطلبون إنشاء متجر إلكتروني متعدد الأصناف وبمميزات معينة، ويمكنك حينها إنشاء مشروع يسهل على العملاء هذه العملية، وبعد الإنتهاء من المشروع يمكنك بيعه في شكل خدمة SAAS أو منتج بإشتراك شهري على سبيل المثال.
    في كثير من الأحيان ستجد أن الفكرة التي لديك قام أحد ما بتنفيذها بالفعل، لكن هذه ليست مشكلة، فبإمكانك تحليل المنافسين ومعرفة المميزات التي يقدمونها والعيوب التي لديهم، مثل سعر عالي مقارنة بالخدمة أو بطء في الدعم الفني أو حنى مشاكل تقنية مختلفة، وبذلك تستطيع تحسين المنتج الخاص بك أيضًا.
    لا يمكن الجزن بشكل حاسم عن الوقت المستغرق في إنشاء أي تطبيق حتى وإن كانت مواصفات التطبيق معروفة ومحددة بالفعل، لأن هذا الأمر يختلف من مطور لآخر، فيمكن لمطور ما أن يقوم بإنشاء مدونة من الصفر في يومين فقط، بينما يمكن لمطور آخر أن يقوم بإنشاء نفس المدونة في أسبوع مثلًا، والفرق هنا يكمن في الكثير من الأشياء مثل الخبرة وطريقة التنظيم والتقنيات المستخدمة لإنشاء المشروع .. إلخ.
    ولن يستطيع أحد أن يخبرك عن الوقت الذي سوف تستغرقه أنت في إنشاء أي مشروع، فأنت الوحيد من يمكنه تحديد هذا الأمر، وذلك بناء على تجربتك في إنشاء المشاريع سابقًا.
  8. إجابة سامح أشرف سؤال في الحصول على API لعرض و تحميل حلقات الانمي مثل أنمي سلاير كانت الإجابة المقبولة   
    كل حلقات الأنمي والأفلام والمسلسلات والمسرحيات .. إلخ لها حقوق ملكية وفكرية للأستوديوهات التي قامت بصنعها أو لقنوات التلفاز التي تقوم بعرضها، لذلك لن تجد API مجاني يوفر تحميل أو مشاهدة الحلقات بأي شكل من الأشكل وكل التطبيقات والمواقع التي تقوم بتوفير مشاهدة الحلقات أو تحميلها بشكل مجاني تقوم بسرقة هذه الحقوق وهذا الأمر مخالف للقانون بالطبع، لذلك لن تجد أيًا من هذه التطبيقات موجودة على متجر Play على سبيل المثال أو لن تجد إعلانات جوجل أدسنس على أحد هذه المواقع، وذلك لأن جوجل تقوم بمنع وحظر المحتوى المُقرصن pirated content.
    لكن يمكنك الحصول على API مجاني يعرض لك معلومات عن مسلسلات الأنمي والأفلام مثل Jikan أو MyAnimeList API ولكن لا يوفر أي من هذه المصادر مشاهدة الحلقات أو تحميلها بأي شكل من الأشكال، وذلك لأن هذا الأمر مخالف للقانون كما ذكرت سابقًا.
    ما يقوم به تطبيق مثل Anime Slayer هو تخزين روابط مشاهدة الحلقات عبر خوادم ok.ru أو 4shared أو غيرها وتكون هذه الروابط عبارة عن embedded URL بالطبع لكي يمكن لهذه الخوادم إضافة إعلانات عليها، وبعد ذلك يقوم التطبيق بمحاولة إستخراج روابط المشاهدة المباشرة من هذه الصفحات وتوفيرها للمستخدم وهذا يعرف بمجال سحب البيانات Web Scraping، بالتأكيد سيكون هناك الكثير من الروابط التي لا تعمل لأن هذه الخوادم تقوم بحذفهال بإستمرار وفقًا لسياستها التي تمنع المحتوى المقرصن أيضًا.
  9. إجابة سامح أشرف سؤال في كيف نحقق مفهوم Load balancing أي توزيع الحمل على المخدمات باستخدام خادوم nginx كانت الإجابة المقبولة   
    يمكن إعداد خادم Nginx كموزع حمل Load Balancer بإستخدام أحد الآليات مثل round-robin أو least-connected أو ip-hash وهنا شرح مبسط عن كل آلية منهم:
    round-robin: في هذه الطريقة يتم تحديد كل خادم بالتتالي وفقًا للترتيب الذي قمت بتعيينه في ملف الإعدادات، أي يتم إرسال الطلب الأول إلى الخادم الأول ثم الطلب الثاني إلى الخادم الثاني وهكذا. هذا يوازن عدد الطلبات بالتساوي للعمليات القصيرة. وهذه هي الطريقة الإفتراضية التي يعمل بها nginx. least-connected: يتم تعيين الطلب التالي للخادم الذي لديه أقل عدد من الاتصالات النشطة active connection. ip-hash: في هذه الطريقة يتم استخدام دالة التجزئة hash-function لتحديد الخادم الذي يجب أن يقوم بمعالجة الطلب (بناءً على عنوان IP الخاص بالعميل). في الأساس، كل ما عليك فعله هو إعداد nginx مع تعليمات حول نوع الاتصالات التي يجب الاستماع إليها ومكان إعادة توجيهها. وذلك من خلال إنشاء ملف configuration جديد باستخدام أي محرر نصوص. على سبيل المثال:
    sudo nano /etc/nginx/conf.d/load-balancer.conf الآن في هذا الملف يجب تعريف جزئين رئيسيين، وهما upstream و server، على النحو التالي:
    http { upstream backend { # نضع هنا عناوين الخوادم التي سيتم إستخدامها server 10.1.0.101; server 10.1.0.102; server 10.1.0.103; } # لاحظ أن اسم upstream و proxy_pass يجب أن يكونا متطابقين. # في هذه الحالة تم إستعمال كلمة backend كاسم لهما server { listen 80; location / { proxy_pass http://backend; } } } الآن يمكن حفظ الملف (عبر الضغط على Ctrl + O) والخروج من محرر النصوص (عبر الضغط على Ctrl + X).
    نحتاج الآن إلى إستبدال ملف الإعدادات السابق بملف الإعدادات الإفتراضي، وذلك عبر الأوامر التالية:
    # في Debian و Ubuntu sudo rm /etc/nginx/sites-enabled/default # في نظام CentOS sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.disabled الآن يجب إعادة تشغيل خادم nginx مرة أخرى وذلك عبر الأمر:
    sudo systemctl restart nginx طريقة round-robin هي المستخدمة بشكل إفتراضي لذلك لا حاجة لتعديل الملف السابق مرة أخرى، بينما يُمكن تغير الآلية المستعملة في الخادم لموازنة الحمل عبر تعديل قسم upstream في ملف الإعدادات السابق، كالتالي:
    لإستخدام طريقة least-connected:
    upstream backend { least_conn; server 10.1.0.101; server 10.1.0.102; server 10.1.0.103; } لإستخدام طريقة ip-hash:
    upstream backend { ip_hash; server 10.1.0.101; server 10.1.0.102; server 10.1.0.103; }  
  10. إجابة سامح أشرف سؤال في كيف أقوم بعملية رفع مشروع Django على الاستضافة كانت الإجابة المقبولة   
    يُمكن إستخدام منصة Heroku كما وضح شرف الدين سابقًا أو يمكن حتى إستخدام أي سيرفر إفتراضي VPS من البداية من خلال الخطوات التالية:
    المتطلبات
    في البداية نحتاج إلى إنشاء الخادم وضبطه في السحابة من خلال أحد خدمات شركات الإستضافة مثل DigitalOcean أو CloudNode، يمكنك أن تشتري أي خادم ويب للتجربة، وسيتم محاسبتك بالساعة (حسب وقت إستعمالك للخادم منذ وقت الشراء)، وقد تتبع شركات إستضافة خطط أخرى غير المحاسبة بالساعة.
    ضبط بيئة Virtualenv جديدة
    نحتاج الآن إلى إعداد بيئة وهميّة virtualenv حيث سيتم تخزين ملفات المشروع وحزم Python أيضًا. إذا كنت لا تستخدم virtualenv ، فقم ببساطة بإنشاء المجلد الذي سيتم تخزين ملفات مشروع Django فيه وانتقل إلى الخطوة التالية.
    يمكنك تثبيت وإعداد Vitualenv من خلال الأوامر التالية:
    sudo apt-get install python-virtualenv virtualenv /opt/myproject الآن بعد تثبيت وإعداد بيئة وهميّة Vitualenv للمشروع نحتاج إلى تفعيلها لكي نتمكن من تثبيت المكتبات والحزم المستخدمة في المشروع، يوجد ملف باسم activate في مجلد bin في البيئة الوهميّة التي تم إنشائها سابقًا:
    source /opt/myproject/bin/activate يمكن الإطلاع على المزيد حول البيئة الوهمية Vitualenv من خلال هذه المقالة:
    كل المتبقي في هذه الخطوة هو تثبيت Django من خلال الأمر التالي:
    pip install django ملاحظة: يجب تنفيذ الأمر السابق بعد تفعيل البيئة الوهميّة مباشرة وليس في أي نافذة Terminal أخرى، لكي يتم تثبيت Django في البيئة الوهمية وليس بشكل عام على النظام.
    إنشاء قاعدة بيانات المشروع
    في الغالب يتم إستخدم PostgreSQL كخادم قاعدة بيانات. لإنشاء قاعدة بيانات باستخدام PostgreSQL، قم بتنفيذ الأمر التالي:
    sudo su - postgres الآن يمكن تنفيذ الأمر التالي لإنشاء قاعدة بيانات جديدة (يمكن إختيار أي اسم في هذه الخطوة):
    createdb mydb ولضمان حماية أكبر على قاعدة البيانات سوف نقوم بإنشاء مستخدم جديد وإعطائه صلاحيات التحكم في قاعدة البيانات التي قمنا بإنشائها:
    createuser -P psql GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser; في الأمر الأول سوف يتم السؤال عن اسم المستخدم الجديد وكلمة السر الخاصة به وبعض المعلومات الأخرى، ثم سيتم إعطائه الصلاحيات اللازمة من خلال جملة SQL الأخيرة.
    إذا لم يكن المشروع يستخدم PostgreSQL كخادم قاعدة بيانات، فستحتاج إلى التحقق من الوثائق حول كيفية إنشاء قاعدة بيانات لخادم قاعدة البيانات الذي تختاره.
    ضبط خادم Nginx
    نحتاج إلى ضبط خادم Nginx لكي يتمكن من عرض موقعنا. وذلك عبر تشغيل الأمر التالي لإنشاء ملف configuration :
    sudo nano /etc/nginx/sites-available/myproject الأمر السابق سوف يقوم بإنشاء ملف جديد والبدء في تحريره عبر برنامج nano.
    الآن يجب كتابة التالي لكي يتمكن خادم Nginx من التعرف على مكان المشروع وكيفية تشغيله:
    server { server_name yourdomainorip.com; access_log off; location /static/ { alias /opt/myenv/static/; } location / { proxy_pass http://127.0.0.1:8001; proxy_set_header X-Forwarded-Host $server_name; proxy_set_header X-Real-IP $remote_addr; add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"'; } } يمكن الآن حفظ الملف عبر الضغط على Ctrl + O ثم إغلاق الملف عبر الضغط على Ctrl + X
    لكي يتعرف Nginx على الملف السابق الذي قمنا بإنشائه يجب تنفيذ الأوامر التالية:
    cd /etc/nginx/sites-enabled sudo ln -s ../sites-available/myproject sudo service nginx restart إن ظهر خطأ كالتالي:
    server_names_hash, you should increase server_names_hash_bucket_size: 32 لحل المشكلة يجب تعديل الملف /etc/nginx/nginx.conf وإلغاء التعليق عن السطر التالي:
    server_names_hash_bucket_size 64; حتى الآن تم إعداد الخادم بشكل سليم ويتبقى أن نرفع ملفات مشروع Django نفسه إلى الخادم، ويمكن إستخدام أي بروتوكول لنقل أو إدارة الإصدارات مثل FTP, SFTP, SCP, Git, SVN، ويفضل إستخدام Git نظرًا لأنه الأسرع والأسهل في التثبيت والإعداد والأسرع في نقل الملفات أيضًا، لذلك يجب رفع المشروع على مستودع في أحد المواقع مثل GitHub أو GitLab .. إلخ، والحصول على رابط المستودع حيث سنقوم بإستخدامه في الخطوة التالي:
    إذا لم يكن لديك Git مثبت مسبقًا، فيمكن تثبيته عبر الأمر التالي:
    sudo apt-get install git نحتاج الآن إلى إنشاء مجلد للمشروع في البيئة الوهمية التي قمنا بإنشائها في الخطوات الأولى وتحميل نسخة من ملفات المشروع إليه:
    cd /opt/myproject mkdir myproject cd myproject git clone https://github.com/path/to/repo . ملاحظة: يحتوي الأمر الأخير على نقطة . وهي تشير إلى المجلد الحالي الذي سيتم تنزيل الملفات إليه.
    تثبيت وإعداد خادم التطبيقات App Server
    نحتاج الآن إلى إستخدام اداة مثل gunicorn لكي تعمل كخادم HTTP وتدير الزيارات إلى المشروع، لذلك سجب تثبيتها وجعل هذا الخادم يستمع إلى الزيارات من المنفذ 8001 الذي قمنا بإعداده في خطوة إعداد Nginx السابقة:
    source /opt/myproject/bin/activate pip install gunicorn gunicorn_django --bind yourdomainorip.com:8001 يمكنك الآن الضغط على Ctrl + z ثم كتابة "bg" لكي يعمل المشروع في الخلفية.
    ضبط إعدادات المشروع
    الخطوة الأخيرة هي إعداد المشروع نفسه وتغير بعض الإعدادات الخاصة به لكي يتعمل بشكل سليم وبدون مشاكل. في البداية سوف نقوم بتعديل ملف settings.py من خلال الأمر التالي:
    sudo nano /opt/myproject/myproject/settings.py ويجب تعديل وضع التطوير Development Mode عبر تغير قيمة المتغير DEBUG إلى False:
    DEBUG = False أيضًا يجب إعداد قاعدة البيانات من خلال تعديل DATABASES:
    DATABASES = { 'default': { 'ENGINE': 'django.db.backends.psycopg2', 'NAME': 'mydb', # database name. # The following settings are not used with sqlite3: 'USER': 'myuser', 'PASSWORD': 'password', 'HOST': '', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP. 'PORT': '', # Set to empty string for default. } } كما يجب تعديل مسارات الملفات الثابتة Static Files من خلال تعديل المتغير STATIC_ROOT و STATIC_URL، كالتالي:
    STATIC_ROOT = '/opt/myproject/static/' STATIC_URL = '/static/' الآن يمكن حفظ المشروع والتوجه إلى المجلد الذي يحتوي الملف manage.py ثم تنفيذ الأمر التالي:
    python manage.py collectstatic سيجمع هذا الأمر جميع الملفات الثابتة Static Files في المجلد الذي قمنا بتعيينه في ملف settings.py أعلاه.
    هذا كل شيء، يمكن الآن زيارة الموقع عبر IP الخادم VPS أو ربطه بنطاق/مجال Domain معين. وفي هذه الحالة ستحتاج إلى شراء نطاق Domain لكي تتمكن من تشغيل مشروعك عبر الإنترنت، حيث أن شركات الإستضافة تمنحك الخادم فقط في أغلب الأحيان، لذلك يجب أن تقوم بشراء نطاق لموقعك بنفسك من خلال أحد شركات الإستضافة مثل namechape أو GoDaddy ..إلخ ، لذلك يجب أن يكون لديك مجال يشير إلى خادم الويب الذي تم إنشاؤه حديثًا.
  11. إجابة سامح أشرف سؤال في كيف أحصل على شهادة SSL لتشفير اتصال موقعي كانت الإجابة المقبولة   
    لكي يُمكن تثبيت وإستخدام شهادة SSL على موقع معين، يجب أن يكون الموقع مستضاف على خادم خاص VPS أو dedicated server مع إمكانية التحكم به عبر سطر اللأوامر من خلال SSH أو أي طريقة أخرى، كما يجب أن يكون لديكِ صلاحيات لإستخدام الأمر sudo. بعد التأكد من وجود كل المتطلبات السابقة، يمكن البدء في الخطوات التالية:
    أولًا يجب تسجيل الدخول إلى الخادم عبر SSH بإستخدام حسساب مستخدم لديه صلاحيات إستخدام الأمر sudo ثانيًا يجب تثبيت Snapd والذي يأتي مثبيت مسبقًا على خوادم Ubuntu 16.04 وما بعد ذلك، لكن إن لم يكن مثبتًا مسبقًا لديكِ، فيمكن تنفيذ هذه الأوامر لتثبيته من جديد: sudo apt update sudo apt install snapd sudo snap install core  
    حذف حزم Certbot: في كثير من الأحيان يحتوي النظام على حزم خاصة بــ Certbot مسبقًا، ويجب حذف هذه الحزم قبل عملية تثبيت Certbot snap الذي سيسمح لنا بتثبيت شهادة SSL، لإلغاء تثبيت Certbot يمكن تنفيذ أحد الأوامر التالية حسب نظام التشغيل الذي لديكِ: sudo apt-get remove certbot sudo dnf remove certbot sudo yum remove certbot  
    الآن سنقوم بتثبيت Certbot Snap من خلال تنفيذ الأمر التالي: sudo snap install --classic certbot وللتأكد من أن عملية التثبيت تمت بنجاح وأنه يمكن تشغيل وإستخدام Certbot، يُمكن تنفيذ الأمر التالي:
     
    sudo ln -s /snap/bin/certbot /usr/bin/certbot  
    الآن يمكن الإختيار بين أن يقوم certbot بتعديل إعدادات خادم Apache وتثبيت شهادة SSL تلقائيًا أو تحميل الشهادة فقط، وذلك عبر أحد الأوامر التالية:
    السماح لـ Certbot بتعديل إعدادات Apache: sudo certbot --apache
    تحميل الشهادة فقط: sudo certbot certonly --apache ملاحظة: إن كان الخادم يعمل بـ Nginx، فيمكن تبديل apache بـ nginx في الأوامر السابقة، وسيعمل كل شيء على ما يرام.
    الآن تم تثبيت الشهادة بنجاح، ويمكن تحديث الشهادة كل فترة عبر الأمر التالي: sudo certbot renew --dry-run sudo certbot renew الأمر الأول للتحقق فقط من أن عملية تحديث الشهادة تتم بنجاح، أما الأمر الثاني فهو ما يقوم بتحديث الشهادات بالفعل.
      يمكن التأكد من أن شهادة SSL تعمل بنجاح من خلال زيارة رابط الموقع عبر بروتوكول HTTPS وليس HTTP مثل https://www.example.com.
    ملاحظة: عند إستخدام certbot والسماح له بتعديل إعدادات الخادم، يقوم بتوجيه الزيارات التي تتم من خلال HTTP إلى HTTPS تلقائيًا.
  12. إجابة سامح أشرف سؤال في كيف أستطيع استخدام عبارة CASE ضمن الاستعلام عن طريق JOIN في SQL كانت الإجابة المقبولة   
    عند ضم جدولين أو أكثر تكون القيم التي تقوم بضمها في بعض الأحيان غير متتطابقة تمامًا بين الجداول. وهناك العديد من الطرق لحل هذا الأمر، ومن ضمن هذه الطرق يمكن إستخدام جملة CASE عند ربط الجداول معًا، وذلك عند تحديد قيمة الحقل مكان ON.
    بفرض أن لدينا جدول orders يحتوي على معلومات عن طلبات العملاء وهو على الشكل التالي:

    لاحظي كيف أن لنفس العميل أكثر من قيمة cust_num متشابهة.
    وأيضًا لدينا الجدول cust_table والذي يحتوي على معلومات حول العملاء أنفسهم:

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

    لاحظي وجود قيم NULL في حقل residence وذلك لعدم تشابهة قيمة الحقل cust_num بين الجدولين.
    لحل هذه المشكلة، يمكن الإستعانة بجملة CASE عند الربط بين الجدولين كالتالي:
    SELECT a.*, b.residence FROM orders AS a LEFT JOIN cust_table AS b ON CASE -- إزالة الرمز -EC من نهاية رقم العميل cust_num إن وجد WHEN a.cust_num LIKE '%-EC' THEN SUBSTRING(a.cust_num, 1, LEN(a.cust_num) - 3) -- في حالة لم يتم العثور على الرمز -EC في رقم العميل فلا حاجة لإستخدام الدالة SUBSTRING ELSE a.cust_num END = b.cust_num ORDER BY order_year عند تنفيذ الإستعلام السابق سوف تكون النتيجة كالتالي:

    بهذا الشكل لن يحتوي الجدول على قيم NULL وسيتم تعويضها بالبيانات بشكل سليم.
    لمعرفة المزيد حول CASE في SQL يمكن الإطلاع على هذه المقالة:
    أو من خلال موسوعة حسوب حول لغة SQL من هنا
  13. إجابة سامح أشرف سؤال في ما هي أداة puppet وكيف نحقق من خلالها مفهوم DevOps كانت الإجابة المقبولة   
    أداة Puppet هي أداة لإدارة البرامج تتضمن لغتها التعريفية لوصف إعدادات النظام. توفر Puppet حل يعتمد على لأتمتة العمليات بأقل قدر من المعرفة البرمجية لاستخدامه. يتم إستخدام برنامج الأتمتة Puppet لغة Puppet التعريفية لإدارة مراحل مختلفة من دورة حياة البنية التحتية لتكنولوجيا المعلومات IT، بما في ذلك التصحيح patching، والإعداد configuration، وإدارة نظام التشغيل والتطبيقات عبر مراكز بيانات المؤسسة Data Centers والبنى التحتية السحابية Cloud Structure.
    يتم إستخدام برنامج Puppet كبرنامج مفتوح المصدر تحت رخصة GPL حتى الإصدار 2.7.0، وتحت رخصة Apache في الإصدارات اللاحقة، كما توجد نسخة مدفوعة للمؤسسات باسم Puppet Enterprise وتحمل ترخيصًا خاصًا.
    يتبع Puppet عادةً بنية الخادم - العميل Client - Server. يُعرف العميل باسم الوكيل Agent ويُعرف الخادم باسم الرئيس Master. يمكن أيضًا استخدامه كتطبيق مستقل يتم تشغيله من سطر الأوامر للاختبار والإعدادات البسيطة. حيث يتم تثبيت Puppet Server على خادم واحد أو أكثر، ويتم تثبيت Puppet Agent على جميع الأجهزة التي يريد المستخدم إدارتها. يتواصل Puppet Agents مع الخادم Master ويقومون بإحضار تعليمات التكوين configuration. يقوم كل Agent بعد ذلك بتطبيق هذه التعليمات على النظام ويرسل تقرير الحالة status report إلى الخادم Master مرة أخرى.
    يمكن للأجهزة تشغيل Puppet Agent كبرنامج خفي daemon، يمكن تشغيله بشكل دوري كوظيفة cron أو يمكن تشغيله يدويًا عند الحاجة.
    هذه التعليمات تكتب بإستخدام لغة Puppet التعريفية Puppet declarative language على الصيغة التالية:
    type { 'title': attribute => value }  
  14. إجابة سامح أشرف سؤال في ما هي أداة ImageMagick وكيف أستفيد منها في موقعي في تعديل ملفات الصور كانت الإجابة المقبولة   
    أداة ImageMagick عبارة عن برنامج مجاني يتم تقديمه كتوزيع ثنائي جاهز للتشغيل أو ككود مفتوح المصدر يمكنك استخدامه ونسخه وتعديله وتوزيعه في كل من التطبيقات المفتوحة والمملوكة. يتم توزيعه بموجب ترخيص Apache 2.0 مشتق.
    يمكن إستخدام هذا البرنامج من خلال عشرات المكتبات في العديد من اللغات مثل PHP و Python و JavaScript و Ruby و pascal و Perl و C و C++ و Go و غيرها الكثير. يمكنك الإطلاع على هذه المكتبات من خلال صفحة Develop من هنا.
    على سبيل المثال، يمكن تحويل الصور من نوع png إلى jpg على النحو التالي:
    from wand.image import Image with Image(filename='inp.png') as img: # فتح الصورة الأصلية بصيغة png img.format = 'jpeg' img.save(filename='out.jpg') # حفظ الصورة باسم جديد حتى يمكن إستخدام مكتبة wand السابقة يجب أولًا تثبيت برنامج libmagickwand من خلال الكود التالي:
    sudo apt-get install libmagickwand-dev ثم يمكن تثبيت المكتبة من خلال الأمر التالي:
    pip install Wand هنا أيضًا نفس المثال السابق ولكن باستخدم لغة PHP من خلال مكتبة imagick:
    <?php $im = new Imagick('image.png'); $im = $im->flattenImages(); $im->setImageFormat('jpg'); $im->writeImage('image.jpg');  
  15. إجابة سامح أشرف سؤال في ماهي خطوات رفع قاعدة البيانات MySQL على الاستضافة كانت الإجابة المقبولة   
    يمكنك أن تستخدم سطر الأوامر Command Line لإستخراج وإستدعاء قواعد البيانات خصوصًا إن كانت كبيرة الحجم للغاية، ولكي لا تنتظر تحميل الصفحة في phpMyadmin أو خطأ timeout عندما يتم إستخراج قاعدة البيانات يفضل أن تستخدم سطر الأوامر للقيام بهذه المهمة. أيضًا في كثير من الأحيان لا يكون هنا دعم لـ phpMyadmin على الخادم لذلك لا يتوفر سوى إستخدام سطر الأوامر بشكل إفتراضي.
    تتوفر MySQL على أداة mysqldump التي تسمح لك بإستخراج وإستيراد قواعد البيانات بشكل سهل وسريع، وذلك من خلال تنفيذ الأمر التالي:
    mysqldump -u YourUser -p YourDatabaseName > wantedsqlfile.sql سوف يتم طلب إدخال كلمة السر الخاصة بسمتخدم قاعدة البيانات YourUser.
    ثم لإستيراد قاعدة البيانات على خادم آخر، يمكنك أن تقوم بتنفيذ الأمر التالي:
    mysql -u YourUser -ptmppassword AnotherDatabaseName < wantedsqlfile.sql قم بتغير اسم المستخدم وكلمة السر واسم قاعدة البيانات وسيبدأ عملية إستيراد قاعدة البيانات.
  16. إجابة سامح أشرف سؤال في ما هي أداة Docker وكيف نحقق من خلالها مفهوم DevOps كانت الإجابة المقبولة   
    أداة Docker عبارة عن أداة تستخدم المحاكاة الافتراضية virtualization على مستوى نظام التشغيل لتقديم البرامج في حزم تسمى الحاويات. أي أنه يقدم كل حاوية وكأنها نظام تشغيل منفصل عن غيره من الحاويات. يتم عزل الحاويات عن بعضها البعض وتقوم بتجميع البرامج والمكتبات وملفات التكوين configuration files الخاصة بها؛ يمكن للحاويات التواصل مع بعضهم البعض من خلال قنوات محددة جيدًا. والسبب في إستخدام هذه التقنية بدلًا من الأنظمة الإفتراضية Virtual Systems هو أن جميع الحاويات تشترك في خدمات services نواة نظام تشغيل واحدة، وبالتالي يتم إستخدام موارد أقل بكثير من الأنظمة الإفتراضية Virtual Systems.

    لاحظ كيف أن الحاويات تتشارك نفس النواة الخاصة بنظام التشغيل، مما يسمح بتشغيل عدد أكبر من التطبيقات المعزولة عن بعضها البعض، بينما في الأنظمة الإفتراضية تكون معزولة عن بعضها البعض، ولكنها تستهلك الموارد أكثر.
    كما أن Docker توفر مجموعة مختلفة من الأدوات مثل Docker Hub والتي يمكن رفع الحاويات عليها لتشاركها مع أشخاص محددين او بشكل مفتوح المصدر و Docker Compose التي تسمح بتعريف وتشغيل تطبيقات دوكر متعددة الحاويات. وتستخدم ملفات خاصة مكتوبة بصيغة YAML (مشابهة إلى حدٍ ما من JSON ولكن بدون أقواس).
    تستعمل أداة Docker في الوقت الحالي لنشر تطبيقات الويب، حيث يتم إستخدام نفس الحاوية المستخدمه في عملية التطوير على الخادم Server وبالتالي تقليل المشاكل والإختلافات بين بيئة التطوير على الجهاز المحلي وبيئة الإنتاج Production على الخادم  Server. 
  17. إجابة سامح أشرف سؤال في كيف أتخلص من القيم المكررة في جدول SQL كانت الإجابة المقبولة   
    يمكنك حذف القيم المكررة في عمود معين في جدول ما بطريقة سهلة من خلال تعديل العمود نفسه وإضافة الخاصية Unique إليه، كالتالي:
    ALTER IGNORE TABLE table_name ADD UNIQUE INDEX idx_name (column_name); ستقوم التعليمة السابقة بتعديل العمود وتجعله من نوع Unique أي أن القيم فيه يجب ألا تتكرر (وسيظهر خطأ عند محاولة إضافة صف جديد ويحمل قيمة موجودة بالفعل هذا العمود).
    لاحظ أننا قمنا بإستخدام الكلمة المفتاحية IGNORE والتي تعني تجاهل (حذف) كل الصفوف التي تحتوي على نفس القيمة في هذا العمود.
    ولإعادة العمود إلى ما كان عليه -أي حذف الخاصية UNIQUE من العمود- يمكنك إن تستخدم تعليمة ALTER مرة أخرى كالتالي:
    ALTER TABLE table_name DROP INDEX column_name; ربما تواجهة مشكلة بسبب إضافة الخاصية UNIQUE إلى عمود معين في قواعد بيانات MySQL بمحرك InnoDB، ويمكنك أن تتخطى هذه المشكلة من خلال تغير الطريقة المستخدمه في تعديل الجداول نفسها في قاعدة البيانات ثم إرجاعها مرة أخرى، كالتالي:
    set session old_alter_table=1; ALTER IGNORE TABLE table_name ADD UNIQUE INDEX idx_name (column_name); set session old_alter_table=0;  
  18. إجابة سامح أشرف سؤال في كيفية إضافة ملف sitemap.xml في Nextjs كانت الإجابة المقبولة   
    يمكنك أن تستخدم حزمة next-sitemap والتي تسمح لك بتوليد ملف sitemap.xml وكذلك ملف robots.txt، كما أنها تقوم بإنشاء ملف sitemap.xml بناءًا على الملفات من نوع Static وكذلك pre-rendered وصفحات SSR بشكل تلقائي.
    لتثبيت الحزمة نفذ الأمر التالي:
    # إن كنت تستخدم yarn كمدير للحزم yarn add next-sitemap -D # أو من خلال NPM npm i next-sitemap لتعمل هذه الحزمة تحتاج إلى ملف يحتوي على الإعدادات الرئيسية وهو ملف next-sitemap.js، لذلك قم بإنشاء هذا الملف في مجلد المشروع الرئيسي الخاص بك وأكتب محتواه كالتالي:
    module.exports = { siteUrl: process.env.SITE_URL || 'https://example.com', generateRobotsTxt: true, // سطر إختيار لتوليد ملف robots.txt تلقائيًا // ... } لاحظ أننا قمنا بالحصول على عنوان الموقع من خلال ملف .env مباشرة، حيث تدعم الحزمة على الحصول على المتغيرات من ملف .env بشكل تلقائي.
    الآن لتشغيل الحزمة ولتوليد ملف sitemap.xml (و ملف robots.txt) قم بإضافة أمر next-sitemap إلى ملف package.json، على النحو التالي:
    { "build": "next build", "postbuild": "next-sitemap --config next-sitemap.js" } إن كان لديك عدد كبير من المسارات والملفات في المشروع يمكنك أن تقوم بتقسيم ملف sitemap.xml لعمل ملفات sitemap فرعية، وذلك من خلال تعديل ملف next-sitemap.js وإضافة الخاصية sitemapSize، كالتالي:
    module.exports = { siteUrl: 'https://example.com', generateRobotsTxt: true, sitemapSize: 1000, } من خلال عمل التعديل السابق على ملف الإعدادات، ستقوم الحزمة بتخزين المسارات والملفات وعندما يزيد هذه المسارات عن 1000 سوف يتم تقسيهم إلى ملفات فرعية مثل sitemap-1.xml و sitemap-2.xml بالإضافة إلى عمل ملف sitemap.xml رئيسي كفهرس للملفات الأخرى (وهذا الأمر تدعمه كل محركات البحث المعروفة وتنصح به أيضًا).
    يمكنك الإطلاع على مزيد من الخيارات والإعدادات التي تقدمها هذه الحزمة من خلال صفحتها على GitHub.
  19. إجابة سامح أشرف سؤال في حقن جمل update و insert في SQL كانت الإجابة المقبولة   
    يمكن إستخدام جملة INSERT أو UPDATE في عملية حقن جمل SQL وذلك عند محاولة إكتشاف أو إستغلال ثغرات SQL Injection حيث يمكن للمخترق Hacker أن يقوم بإضافة بريد إلكتروني جديد كمسئول Admin أو حتى يقوم بتغير كلمة مرور أحد المستخدمين أو أحد المسئولين، فعلى سبيل المثال، إن كان لدينا حقل لعملية بحث، على النحو التالي:
    <form action="search.php" method="GET"> <input type="text" name="query" placeholder="Search ..." /> </form> وتتم عملية المعالجة من خلال صفحة search.php على النحو التالي:
    <?php // إستخدام ما أدخله المستخدم في جملة SQL بشكل مباشر في $result = mysql_query("SELECT * FROM posts WHERE title LIKE '%" . $_GET['query'] . "%'"); الكود السابق خطير للغاية لأنه يُمكن المستخدم أن يقوم بتنفيذ جمل SQL من داخل حقل البحث، فما الذي سيحدث إن قام شخص ما بكتابة الكود التالي في حقل البحث:
    post title%'; DELETE FROM users; -- إن قام أحد ما بكتابة النص السابق في حقل البحث، فستكون جملة SQL التي يتم تنفيذها في النهاية كالتالي:
    SELECT * FROM posts WHERE title LIKE '%post title%'; DELETE FROM users; --%' بهذا الشكل سوف يتم أولًا البحث عن منشور بعنوان مشابهة ثم سيتم حذف كل المستخدمين من جدول users وهذا ما لا نريده بالطبع، وبالمثل يمكن إستخدام جمل INSERT أو UPDATE لإضافة أو تغير مسئولين في الموقع، وذلك من خلال كتابة تعليمة مشابهة للتالي:
    post title%'; INSERT INTO users(email, name, password, is_admin) VALUES('hacker@mail.com', 'Hacker', '123456', 1); -- الجملة السابقة سوف تؤدي إلى إضافة مستخدم جديد في جدول users وجعل صلاحياته admin، أيضًا يمكن إستخدام جملة UPDATE لتغير كلمة سر أي مستخدم على سبيل المثال:
    post title%'; UPDATE users SET password = '123456' WHERE email = 'admin@mail.com'; -- الجملة السابقة سوف تقوم بتغير كلمة المرور للمسئول (أو المستخدم) الذي لديه بريد إلكتروني admin@mail.com.
    بهذه الطريقة يمكن أن يتم إستخدام جمل UPDATE  أو INSERT لحقن تعليمات SQL في قاعدة البيانات. بالطبع لن يكون المخترق أو مُختبِر الإختراق على علم بأسماء الجداول أو الأعمدة في الغالب لكن من خلال بعض جمل SQL الأخرى التي سيقوم بحقنها سيمكنه معرفة كل الجداول في قاعدة البيانات وكذلك أسماء وأنواع الأعمدة في كل جدول، ويعتمد الأمر في النهاية التجربة ومحاولة إستغلال ثغرة SQL Injection بأي طريقة ممكنة.
    يمكنكِ الإطلاع على هذه المقالة التي توضح بتفصيل أكثر ما هي ثغرات SQL Injection وكيفية الحماية منها:
    أيضًا لمعلومات أكثر حول حماية المواقع يمكنكِ الإطلاع على هذه المقالة هنا:
    يجدر بالذكر أن هناك الكثير من المواقع التي تقدم مكافأت لكل من يكتشف ثغرات مشابهة في خدماتها وتسمى المكافأة في هذه الحالة bug bounty ويوجد الكثير من المواقع التي تقدم برامج لإكتشاف الثغرات مثل hackerone و bugcrowd و Facebook أيضًا
  20. إجابة سامح أشرف سؤال في كيف أضيف حقل لجدول في قاعدة البيانات وأحدد له قيمة افتراضية SQL كانت الإجابة المقبولة   
    يمكنك إضافة عمود لجدول موجود بالفعل من خلال الصيغة التالية:
    ALTER TABLE table_name ADD column_name BOOLEAN DEFAULT false; قد تختلف الصيغة السابقة وفقًا لنوع وإصدار نظام قاعدة البيانات لديك، ويمكنك تجربة الجمل التالية إن لم تعمل الجملة السابقة:
    ALTER TABLE table_name ADD column_name BOOLEAN SET DEFAULT false; وإن كنت تستعمل SQL Server، فيمكنك إستخدام الجملة التالية:
    ALTER TABLE table_name add [column_name] BIT default 'FALSE' NOT NULL; لاحظ أنه تمت إضافة NOT NULL إلى الجملة السابقة لأن النوع BIT يقبل قيمة واحدو من ثلاثة قيم (كمدخل)، وهم True و False و NULL لذلك قمنا بإضافة NOT NULL حتى لا يتم تخزين قيمة فارغة في الحقل ويظهر بدلًا من هذا خطأ عند محاولة ذلك.
    أيضًا يمكن إستخدام '1' بدلًا من 'TRUE' و "2" بدلًا من "FALSE" في الجملة السابقة وسيعمل كل شيء على ما يرام.
    يمكنك الإطلاع أكثر حول جملة ALTER من خلال موسوعة حسوب من هنا (تعديل الجدول ALTER TABLE - موسوعة حسوب).
  21. إجابة سامح أشرف سؤال في [Mime type ] رفع ملفات rar كانت الإجابة المقبولة   
    لا تقرأ المتصفحات فعليًا الملف الذي يتم تحديده وإنما يتم تحديد نوع الملف بناءً على امتداده (extension)؛ سيعطي ملف صورة PNG الذي تمت إعادة تسميته إلى .txt "text/plain" وليس "image/png". بالإضافة إلى أنه يمكن الاعتماد على file.type بشكل عام فقط لأنواع الملفات الشائعة مثل الصور ومستندات HTML والصوت والفيديو.
    أيضًا قد ترجع امتدادات الملفات غير المألوفة (مثل صيغة rar أو الصيغة sss) نص فارغ "". يُنصح المطورون بعدم الاعتماد على هذه الخاصية طريقة وحيدة للتحقق من نوع الملف، ويجب أن يتم التأكد من نوع الملف من خلال الواجهة الخلفية Backend أيضًا، لأنه يمكن التلاعب بكود JavaScript بسهولة في المتصفح.
    لحل المشكلة مؤقتًا في الواجهة الأمامية Frontend في JavaScript يمكنك ان تتأكد من صيغة الملف zip أو rar وتضيف نص فارغ كـ Mime type على النحو التالي:
    var allowedTypes = ["", 'application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/x-rar', 'application/rar','application/x-rar-compressed','application/force-download','application/octet-stream']; بهذه الطريقة سيتم قبول ملف zip وملفات rar أيضًا، مع العلم أنه سيتم قبول أي ملف آخر بصيغة غير معروفة، لذلك يجب التأكد من أن اسم الملف يتنهي بـ .zip أو .rar
    $(document).ready(function(){ $(".img").change(function(){ var allowedTypes = ["", 'application/x-zip', 'application/zip', 'application/x-zip-compressed','application/force-download','application/x-rar', 'application/rar','application/x-rar-compressed','application/force-download','application/octet-stream']; var file = this.files[0]; // التحقق من الملف من خلال صيغته if (!file.name.endsWith('.zip') && !file.name.endsWith('.rar')){ alert('Restricted File Type, Please Select only ZIP or RAR file'); $(".img").val(''); return false; } }); });  
  22. إجابة سامح أشرف سؤال في كيف يمكننا حذف صفوف محددة من قاعدة البيانات واداراج صفوف جديدة؟ كانت الإجابة المقبولة   
    يمكن حذف أسطر معينة من جدول ما من خلال إستعمال الجملة WHERE وذلك عبر تحديد كالتالي:
    DELETE FROM table_name WHERE id = 1; -- حذف الصف الذي يحتوي على القيمة 1 في العمود id DELETE FROM table_name WHERE name = 'sameh'; -- حذف أي صف لديه القيمة sameh في العمود name DELETE FROM table_name WHERE age < 18; -- حذف أي صف لديه قيمة أقل من 18 في العمود age يمكنك أن تستخدم أي شرط بعد الجملة WHERE وإن تحقق الشرط على صف معين سوف يتم حذفه.
    ملاحظة هامة: إن لم يتم تحديد جملة WHERE في تعليمة SQL السابقة سوف يتم حذف كل محتويات الجدول، فالأمر التالي سوف يقوم بحذف كل الصفوف من جدول users:
    DELETE FROM users; كما يمكن حذف عدد محدود من الصفوف مثل حذف عشرة صفوف فقط حتى وإن تم تحقيق الشروط على أكثر من ذلك، على النحو التالي:
    DELETE FROM table_name WHERE age < 18 LIMIT 10; ستؤدي الإستعلام السابق إلى حذف عشر صفوف فقط من الصفوف التي لديها القيمة أقل من 18 في العمود age.
    لمعرفة المزيد عن تعليمة الحذف يمكنك الإطلاع على توثيقها في موسوعة حسوب من هنا (استعلام DELETE - موسوعة حسوب).
    أما بالنسبة لإضافة صفوف جديدة في جدول ما فيجب أن يتم إستعمال التعليمة INSERT مع تحديد الأعمدة والقيم التي سيتم إضافتها، كالتالي:
    INSERT INTO table_name (name, age) VALUES ('sameh', 22); التعليمة السابقة سوف تقوم بإضافة سطر جديد في الجدول مع وضع القيمة 'sameh' إلى العمود name والقيمة 22 إلى العمود age. لاحظ أيضًا أننا نقوم بإضافة القيم بنفس ترتيب الأعمدة.
    لمعرفة المزيد عن تعليمة INSERT يمكنك الإطلاع على توثيقها في موسوعة حسوب من هنا (استعلام INSERT - موسوعة حسوب).
  23. إجابة سامح أشرف سؤال في هل يمكن العمل بلغة PHP وأنا طالب في الكلية؟ كانت الإجابة المقبولة   
    لغة PHP من أشهر اللغات والأكثر إستعمالًا في الوطن العربي بشكل خاص والعالم بشكل عام، وقد تم عمل مواقع ضخمة بها مثل Wikipedia وFacebook وتم بها إنشاء إطارات عمل كبيرة مثل Laravel وكذلك أنظمة إدارة المحتوى مثل ووردبريس والذي يتم إستعماله في أكثر من 42% من جميع مواقع الإنترنت، مما يعني أنها اللغة الأكثر إستعمالًا من بين كل اللغات الأخرى (في الواجهات الخلفية Backend بالطبع).
    يمكنك ببساطة أن تقوم بفتح أحد مواقع العمل الحر مثل مستقل أو خمسات ومشاهدة الطلبات وستجد أن أغلب طلبات تطوير المواقع تستعمل لغة PHP، مع العلم أن العمل في أحد هذه المواقع لا يتطلب منك شهادة جامعية بل فقط أعمالك وخبرتك.
  24. إجابة سامح أشرف سؤال في استضافة nextjs في vps server كانت الإجابة المقبولة   
    لإستضافة مشروع Next.js في خادم خاص VPS يمكنك إتباع الخطوات التالية:
    إنشاء خادم خاص من أحد شركات الإستاضفة مثل DigitalOcean أو CloudNode
    قبل أي شيء، نحتاج إلى إنشاء الخادم وضبطه في السحابة من خلال أحد خدمات شركات الإستضافة، يمكنك أن تشتري أي خادم ويب للتجربة، وسيتم محاسبتك بالساعة (حسب وقت إستعمالك للخادم منذ وقت الشراء)، وقد تتبع شركات إستضافة خطط أخرى غير المحاسبة بالساعة. ضبط اسم المجال Domain أيضًا ستحتاج إلى شراء نطاق / مجال Domain لكي تتمكن من تشغيل مشروعك عبر الإنترنت، حيث أن شركات الإستضافة تمنحك الخادم فقط في أغلب الأحيان، لذلك يجب أن تقوم بشراء نطاق لموقعك بنفسك من خلال أحد شركات الإستضافة مثل namechape أو GoDaddy ..إلخ ، لذلك يجب أن يكون لديك مجال يشير إلى خادم الويب الذي تم إنشاؤه حديثًا.
    تثبيت وضبط Nginx
    الآن أنت بحاجة إلى برنامج لكي يدير الطلبات التي تصل إلى خادم الويب الذي قمنا بإنشائه في السابق،  يمكنك تنفيذ الأمر التالي لتثبيت Nginx: sudo apt-get update && sudo apt-get install nginx بعد ذلك يجب أن تقوم بالسماح لـ Nginx بأن يمر من خلال جدار الحماية من خلال الأمر التالي:
     
    sudo ufw allow 'Nginx HTTP' الآن يمكنك تشغيل Nginx من خلال الأمر التالي:
     
    systemctl status nginx ومن المفترض أن تظهر لك نتيجة كالتالي:
     
    ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2016-04-18 16:14:00 EDT; 4min 2s ago Main PID: 12857 (nginx) CGroup: /system.slice/nginx.service ├─12857 nginx: master process /usr/sbin/nginx -g daemon on; master_process on └─12858 nginx: worker process لاحظ كلمة active في السطر الثالث، وهذا يعني أن Nginx يعمل الآن بدون مشكلة، يمكنك أن تزور عنوان الخادم من خلال المتصفح وستجد صفحة Welcome to Nginx، كما في الصورة:

    قم بتثبيت Node.js
    لنشر مشروع مبني بإستخدام Next.js (أو أي مشروع آخر مبني بإستخدام JavaScript) ستحتاج إلى تثبيت Node.js وكذلك NPM ، ويمكنك تثبيتهما من خلال الأوامر التالية: curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash - sudo apt-get install -y nodejs أيضًا توجد الكثير من الحزم التي تعتمد على حزمة build-essential والتالي نحتاج إلى تثبيتها من خلال الأمر التالي:
     
    apt-get install -y build-essential الآن يمكنك التأكد من أن كل من Node.js  و NPM قد تم تثبيتهما بشكل سليم من خلال الأمر التالي:
     
    node --version npm --version وسيظهر لك إصدار كل منهما.
    انشر تطبيق Next.js
    الآن نحتاج إلى إرسال الكود إلى الخادم لكي يمكنه العمل، لذلك يمكنك أن تقوم برفع الكود إلى مستودع repo على GitHub إن لم تقم بهذا من قبل (أو يمكنك أن تستعمل بروتوكول FTP  ولكن خطوات تثبيته كثيرة كما أنه بطيء للغاية مقارنة بـ GitHub)، ويمكنك تحميل الكود إلى الخادم من خلال الأمر التالي: git clone https://github.com/your_github_username/your_repository_name.git website سيقوم الأمر التالي بتحميل الكود الخاص بك من GitHub إلى الخادم ، وسيضعه في مجلد باسم website، الآن يجب تثبيت الحزم الخاصة بالمشروع عبر الأوامر التالية:
     
    cd website npm install npm run dev إن ظهر لك نص كالتالي، فأن كل شيء يعمل على ما يرام:
     
    ready - started server on http://localhost:3000 الآن يمكنك الخروج من الأمر الأخير من خلال الضغط على Ctrl + C، ثم تنفيذ الأمر التالي، لإنتاج الكود النهائي للمشروع:
     
    npm run build ستلاحظ أنه تم إنشاء مجلد باسم /.next، والآن ستحتاج إلى حزمة pm2 لكي تتأكد من أن التطبيق يعمل طوال الوقت بدون إنقطاع، ويمكنك تثبيت هذه الحزمة عبر الأمر:
    sudo npm install -g pm2 ثم يجب تشغيل المشروع من خلالها عبر الأمر التالي:
     
    pm2 start --name=website npm -- start  
    قم بضبط Nginx كـ reverse proxy
    كل المتبقي الآن هو إتاحة الموقع للتشغيل عبر إنترنت  cd /etc/nginx/sites-available sudo touch example.com sudo nano example.com بعد ذلك يمكنك إضافة الكود التالي لكي يتم تحويل الطلبات من الإنترنت إلى المنفذ 3000، 
    server { listen 80; listen [::]:80; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name example.com www.example.com; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } تأكد من تغير example.com و www.example.com إلى نطاق الموقع الصحيح
    بعد ذلك ستحتاج إلى تشغيل الملف example.com السابق هذا إلى Nginx عبر الأوامر التالية:
     
    sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx  
    بهذا الشكل يمكنك زيارة الموقع الخاص بك من خلال متصفح الويب عبر زيارة نطاق الموقع بشكل مباشر (سواء بإستخدام www أو بدونها).
  25. إجابة سامح أشرف سؤال في خطأ عند استخدام المكون Image في nextjs كانت الإجابة المقبولة   
    يجب التأكد من مسار الصورة الصحيح، حيث يجب أن تكون صورة محلية local ضمن مشروع next.js أو صورة عامة global ولكن يجب أن يتم إضافة النطاق domain الخاص بالصورة في ملف next.config.js على النحو التالي:
    module.exports = { reactStrictMode: true, images: { domains: ['image-domain-here.com'], } } يجب أن يتم إضافة النطاق بدون بروتوكول HTTP أو HTTPS.
    ملاحظة: عند عمل أي تعديل على ملف next.config.js يجب أن يتم إعادة تشغيل الخادم مرة أخرى، وتتم هذه العملية تلقائيًا في النسخ الحديثة من Next.js. وإن لم تعمل معك، فيجب أن تقوم بذلك يدويًا.
×
×
  • أضف...