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

لوحة المتصدرين

  1. سامح أشرف

    سامح أشرف

    الأعضاء


    • نقاط

      10

    • المساهمات

      2934


  2. إياد أحمد

    إياد أحمد

    الأعضاء


    • نقاط

      6

    • المساهمات

      92


  3. Wael Aljamal

    Wael Aljamal

    الأعضاء


    • نقاط

      6

    • المساهمات

      6975


  4. محمود سامي حسين

    • نقاط

      4

    • المساهمات

      155


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 12/01/21 في كل الموقع

  1. خطأ فورم التسجيل بعد اضافه بعض الحقول اليه الاصدار الثامن من لارافيل . مرفق صورة للخطأ وملف المشروع. myotel.rar
    2 نقاط
  2. عندما أقوم بتشغيل الكود التالي: from selenium import webdriver driver = webdriver.Chrome() أتلقى هذا الخطأ: WebDriverException: Message: 'chromedriver' executable needs to be available in the path. Please look at http://docs.seleniumhq.org/download/#thirdPartyDrivers and read up at http://code.google.com/p/selenium/wiki/ChromeDriver علماً أنني قمت بتنزيل chromedriver لجهازي الذي يعمل بنظام windows من هنا. وبعد تحميل الملف المضغوط قمت بفك ضغطه ووضعه ضمن مجلد التنزيلات downloads، ثم قمت بوضع المسار إلى الملف الثنائي القابل للتنفيذ (C: \ Users \ michael \ Downloads \ chromedriver_win32) في "مسار" متغير البيئة. ما المشكلة؟
    2 نقاط
  3. النوع char لا يستخدم فقط لتخزين حرف واحد، ويوجد منه نوعين رئيسيين: signed char unsigned char إذا كان برنامجك يعتمد على هذا النوع بشكل مباشر، فيجب أن تقوم بإستخدام أحد النوعين السابقين صراحةً، بينما في حالة أردت أن تستخدم هذا النوع للتعبير عن حرف معين فقط فيمكنك أن تستخدم char فقط بدون تحديد الجزء signed أو unsigned وعلى حسب نظام التشغيل الذي تعمل عليه سوف يتم تحديد إشارة النوع تلقائيًا. النوع char يخزن حالة واحدة من 256 قيمة بشكل إفتراضي وعلى كل المصرفات compilers (أي أنه يستغل ما مساحته 8-bit من الذاكرة) ولكن على حسب الإشارة يختلف نطاق هذه القيم، فسنجد أن النوع signed char يقوم بتخزين القيم من -128 إلى 127 (256 حالة)، بينما النوع unsigned char يقوم بتخزين القيم من 0 إلى 255 (256 حالة)، وبالتالي فإن عدد القيم هو نفسه، ولكن النطاق الذي يمكن أن تكون فيه هذه القيم مختلف بين النوعين. طبقًا لما سبق فإن النوع char يحمل قيمة رقمية وليس حرف، ويمكن التأكد من ذلك من خلال الكود التالي: char a {65}; std::cout << a; // A في هذا الكود تم تخزين القيمة 65 في المتغير a وعندما تم طباعة قيمة هذا المتغير ستجد أن الحرف A هو من تم طباعته في سطر الأوامر والسبب هو أن المصرَّف يقوم بتحويل القيمة المخزنة في المتغير من نوع char إلى حرف ASCII إختصارًا لـ American Standard Code for Information Interchange وهو جدول يعبر أن الحروف والأرقام وبعض الرموز بأرقام من بين 0 إلى 127، كالتالي: وفي هذا الجدول ستجد أن القيمة 65 تعبر عن الحرف A ولهذا السبب تم طباعة الحرف A في سطر الأوامر ملاحظة: المتغير a في الكود السابق يحمل القيمة 65 وليس '65' . سبب وجود النوع unsigned char بما النوع int يقوم بتخزين قيمة 4-byte في أغلب أنظمة التشغيل، وبما أن النوع char يخزن أرقام في الأساس كما ذكرت سابقًا، فقد تم إستخدام النوع char لتخزين الأرقام الصغيرة لتحسين أداء البرنامج والتقليل من إستهلاك الذاكرة إلى أقصى حد ممكن، وبالتالي يمكن تخزين أرقام سالبة في هذا النوع (حسب الحاجة) ، مع العلم أنه لا يجب أن تستخدم هذا النوع إلا لتخزين حرف واحد (إلا إذا كنت تعمل على تحسين إستهلاك الذاكرة بشكل كبير). لذلك يتم إستخدام النوع unsigned char في رسومات الحاسوب Computer Graphics كثيرًا، خصوصًا لتخزين الألوان، حيث يتم التعبير عن أي لون من خلال الصيغة RGB (أو RGBA في بعض الأحيان) وهي عبارة عن دمج بين الثلاثة ألوان الرئيسية (الأحمر و الأخصر والأزرق) لتكوين أي لون، وتكون قيمة كل لون من هذه الألوان الثلاثة ما بين 0 إلى 255 ويتم التعبير عن أي لون بهذا الشكل (0 ,0 ,255) (اللون الأحمر) لذلك يتم إستخدام ثلاث قيم من النوع unsigned char للتعبير عن قيمة أي لون.
    2 نقاط
  4. حملت اكثر من مكثبه ولا قدرت استعمل اي واحده منها والسبب هو عدم معرفتي بكيفية تظمين ملفات هذه المكتبات، اقصد لا استطيع العثور على مسار محدد او ملف معين لتضمينه وتشنغل المكتبه، ووجدت بعض المكتبت تقوم بتضمين هذا المسار vendor/autoload.php ولكن عدما ابحث في مجلدات وملفات المكتبه عن هذا المسار لا اجده مطلقا، اعتقد جميع ملفات المكتبه تم تضمينها في الملف autoload.php, ولكن هذا الملف غير موجود او كيف يمكن التعامل معه، اتمنى اي شخص تعامل مع اي مكتبه من هذه الشاكله يشرح لي وللجميع كيف نظم هذه المكتبات والعمل بها خطوة بخطوة لتعم الفائدة، للعلم انا انشئت فورم ورك بسيط، بحيث قمت بتضمين جميع مسارات الملفات في ملف واحد ومن ثم اضمن هذا الملف في اي ملف اريد كتابة كود فيه واستفيد من الكلاسات تبع الفورم ورك خاصتي لكن مع المكتبات الخارجيه لا اعلم كيف يتم تضمين وربط الملفات ببعضها البعضوكيف يمكن الوصول والاستفاده من كلاسات المكتبه، خاصه اانني لا اعلم اين الملف الذي تم تضمين جميع الملفات بداخله
    1 نقطة
  5. عندما أقوم بعمل متغير من نوع double أو float كالتالي: double x {0.1 + 0.2}; // من المفترض أن القيمة تكون 0.3 عندما أقوم بعمل مقارنة بين المتغير السابق والقيمة 0.3 أحصل على false: if((0.1 + 0.2) == 0.3) { // false std::cout << "equal"; } أعلم أن مجموع 0.2 + 0.1 لا يساوي 0.3 بالضبط، ولكن كيف يمكنني أن أقوم بالتحقق من أن القيمة 0.1 + 0.2 تساوي 0.3؟
    1 نقطة
  6. أريد أن أقوم بطباعة نوع المتغير، على سبيل المثال لدي متغير x نوع int وأريد أن أقوم بطباعة الكلمة int (نوع المتغير). يمكنني أن أستخدم type لمعرفة نوع المتغير في Python ، ولكن كيف أقوم بهذا الأمر في لغة ++C؟
    1 نقطة
  7. ما الفرق بين النوع int * const و * int const ، حيث أجد صعوبة في فهم وظيفة كل نوع ومتى أسعمل كل نوع منها .. إلخ أريد أن أعرف متى يجب أن أستعمل كل واحد منهما، ومتى لا أستعمل النوع الآخر، وما إلى ذلك. وهل هناك طرق مختلفة لكتابة نفس النوع بأكثر من طريقة في لغة ++C؟
    1 نقطة
  8. كيف يمكنني العثور على عنصر يحتوي على نص معين، على سبيل في المقطع التالي: <!DOCTYPE html> <html> <body> <button type= “button” >Hsoub Mostql</button> </body> <html> أريد الحصول على العنصر button الذي يحوي النص Hsoub Mostql.
    1 نقطة
  9. يمكنك عرض المسارات باستخدام: php artisan route list
    1 نقطة
  10. إذا تأكد من ملف العرض، وأين يتم إرسال الطلبية (المسار) و http method وتطابقها مع Route حاول أولا إعادة أي بيانات وعرضها في View (لاحظ أن return الأولى تمنع ذلك) بكل حال، بعد إنشاء الغرض يمكن التحقق منه باستخدام خاصية exists $user = User::create($data); if ($user->exists) { // success } else { // failure } في ملفك، سبق وتحققت من data الآن نتأكد من إضافة user
    1 نقطة
  11. ملاحظات: أنت تقوم بإضافة عدة حقول سوية، أي يجب تضمين هذه الحقول في مصفوفة fillable في النوذج لمنع خطأ mass assigment function يعيد قيمة مرة واحدة عند تنفيذ أول تعليمة return وأنت تضع أكثر من واحدة في حال تم تنفيذ أول return لن يتم استكمال التعليمات التالية
    1 نقطة
  12. السلام عليكم ورحمه الله وبركاته قمت بعمل ذلك ولا يظهر خطأ validation error لكن لا يتم عمل submit للبيانات هل أخطئت في كتابه كود المتحكم . مرفق كود المتحكم RegisterController.php
    1 نقطة
  13. هل من الممكن التقاط لقطة شاشة باستخدام Selenium WebDriver ( ليس من خلال Selenium Remote Control)؟
    1 نقطة
  14. لديك مشكلة في الفورم , لم تقم باضافة الخاصية name لأي حقل , كيف سوف نقوم باستقبال البيانات في الواجهة الخلفية اذا لم تضع الخاصية name , لاحظ <input class="form-control @error ('first_name') is-invalid @enderror " id="first_name" type="text" value="{{ old('first_name') }}" placeholder="{{__('radix.Enter your first name')}}" required autocomplete="first_name" /> لا يوجد خاصية name , أرجو منك اضافتها كالتالي لكل حقل <input class="form-control @error ('first_name') is-invalid @enderror " id="first_name" type="text" value="{{ old('first_name') }}" placeholder="{{__('radix.Enter your first name')}}" required autocomplete="first_name" name="first_name" ^^^^^^^^^^^^^^^^^ /> قم باعطاء كل حقل الاسم الخاص به , لتتعامل مع لبيانات المرسلة في الواجهة الخلفية, ثم تأكد من الكود الخاص بالتحقق من البيانات في المتحكم الخاص بتسجيل عضو جديد في المسار التالي App\Http\Controllers\Auth\RegisterController; وجرب عملية التسجيل مرة أخرى
    1 نقطة
  15. بسبب أن لغة مشروعك هي العربية يجب عليك إضافة ملف Validation.php إلى مجلد ar الموجود في المسار التالي myotel\resources\lang\ar يمكنك العثور على هذا الملف في مجلد en في نفس المسار السابق ، كل ما عليك هو نسخ هذا الملف ثم وضعه في مجلد ar مع تغير النصوص الى اللغة العربية في هذا الملف في مجلد ar .
    1 نقطة
  16. ما الخطا في فورم التسجيل التالي : http://otel-by-mshm.herokuapp.com/public/register وما الأخطاء التي قمت بعملها في التصميم الview عند أستعمال @include وهل هذا خطأ ام لا وهل يجب أن أستعمل @yield و @section مستودع المشروع. https://github.com/mahmoudsamyhosein/otel وايضا لماذا يظهر الفورم بصورة خاطئة علي هذا الرابط https://otel-by-mshm.herokuapp.com/public/login ورابط التسجيل يعمل جيدا وما الفرق بين أستعمال {{ asset('asset_name')}} و {{ secure_asset('asset_name')}}
    1 نقطة
  17. لديك خطأ في ذكر الملف admin/theme/css.blade.php فهو يجب أن يذكر كالتالي <?php @include('admin/theme/css') نفس الخطأ السابق إضافة إلى خطأ بذكر اسم الملف admin/theme/js.blade.php فهو يجب أن يذكر أيضا كالتالي <?php @include('admin/theme/js') الفرق هو بالبروتوكول المستخدم في الرابط الذي سينشأ: asset: تستخدم إما HTTP أو HTTPS بحسب بروتوكول الطلب الوارد secure_asset: تستخدم حصرًا HTTPS بغض النظر عن بروتوكول الطلب الوارد
    1 نقطة
  18. كيف يمكننا الوصول إلى كود عنصر ويب ما element source؟ أعلم أنه يمكنني الحصول على عنصر ويب بالشكل التالي: element=webdriverObj.find_element_by_css_selector('#id') # وأنا أعلم أنه يمكنني الحصول على مصدر الصفحة الكامل باستخدام: webdriverObj.page_source # لكن ماذا عن عنصر ويب محدد.. أي هل يوجد شيئ كهذا: element.source # له Html بحيث يعيد كود
    1 نقطة
  19. أريد البدء في استخدام مكتبة Selenium لتنفيذ عمليات استخراج البيانات، لذا أرغب في تثبيتها، ماهي العمليات التي يجب أن أقوم بها؟
    1 نقطة
  20. يمكن استخدام دالة prinf لطباعة مجموعة متغيرات مع تحديد نمطهم int x = 5; int y = 10; printf("%d : %d\n", x, y); سيعطي الخرج التالي: 5 : 10 لاحظ استخدام d% عند طباعة رقم digit نستخدم c عند طباعة محارف Characters نستخدم f عند طباعة أرقام فاصلة عائمة Floats نستخدم d عند طباعة أرقام عشرية Decimals نستخدم s عند طباعة سلاسل نصية Strings specifier Output Example d/i Signed decimal integer 392 u Unsigned decimal integer 7235 o Unsigned octal 610 x Unsigned hexadecimal integer 7fa X Unsigned hexadecimal integer (uppercase) 7FA f Decimal floating point, lowercase 392.65 F Decimal floating point, uppercase 392.65 e Scientific notation (mantissa/exponent), lowercase 3.9265e+2 E Scientific notation (mantissa/exponent), uppercase 3.9265E+2 g Use the shortest representation: %e or %f 392.65 G Use the shortest representation: %E or %F 392.65 a Hexadecimal floating point, lowercase -0xc.90fep-2 A Hexadecimal floating point, uppercase -0XC.90FEP-2 c Character a s String of characters sample p Pointer address b8000000 n Nothing printed. The corresponding argument must be a pointer to a signed int. The number of characters written so far is stored in the pointed location. % A % followed by another % character will write a single % to the stream. % مثال: printf("Hello %s \n", "wael"); // Hello wael printf("Digit: %d \n", 9); // Digit: 9 printf("Float %f \n", 2.23); // Float 2.230000 printf("Float two decimal %.2f", 2.23); // Float two decimal 2.23
    1 نقطة
  21. يمكن تحويل العدد الصحيح لتمثيله كشلشلة نصية من خلال تكرار قسمته على 10 وفي كل مرة أخذ باقي القسمة على 10 مع جمع قيمة المحرف '0' كخرج للمرحلة، فيكون الخرج سلسلة مجموعة محارف بين '0' و '9'. باستخدام خوارزمية عودية: تكرار الاستدعاء طالما n/10 ليس 0 (شرط التوقف) استدعاء الدالة عودياً للخطوة التالية n/10 طباعة باقي قسمة n على 10 + '0' كنتيجة للخطوة الحالية void convert_To_String(int n) { if (n / 10 != 0) { convert_To_String(n / 10); } printf("%d", n % 10 + '0'); } في الحل السابق، لانضطر لعكس جهة المحارف المشكلة للعدد لأن تعليمة الطباعة للخطوة الحالية سيتم تنفيذها لاحقاً بعد انتهاء الاستدعاءات العودية ويمكن الحل باستخدام حلقة: r سلسلة الجواب وستكون من محارف بين 0 و 9 ثم حلقة طالما n لا تساوي 0 سنكرر الخطوات: حساب قيمة باقي قسمة العدد n على 10 إضافة قيمة السلسلة النصية المؤقتة للإجابة قسمة العدد n على 10 إعادة r std::string to_Binary(int n) { std::string r; while(n!=0) { std::string tmp = n % 10 + '0'; r=+temp; n/=10; } return r; }
    1 نقطة
  22. أنت تستعمل المعامل , comma operator هنا وهذا معامل موجود في لغة ++C، وهو المعامل الأقل أهمية في ترتيب التنفيذ (أي له أقل أولوية في عملية التنفيذ)، ويقوم هذا المعامل بتنفيذ الجزء الموجود على اليسار ثم يعيد الجزء الموجود على اليمين، فعلى سبيل المثال في الكود التالي سيتم زيادة قيمة x و سيتم تهيئة المتغير y بالقيمة 3 int x{ 1 }; int y{ (++x, 3) }; // تم إحاطة العملية بأقواس لكي لا يظهر خطأ too many initializer values std::cout << y; // 3 يتجنب المبرمجين إستخدام إستخدام هذا المعامل قدر الإمكان، ما عدا في حلقات for حيث يتم إستخدامه لعمل أكثر من عداد في نفس الحلقة، كما في الكود التالي: #include <iostream> int main() { for (int x{ 0 }, y{ 9 }; x < 10; ++x, --y) std::cout << x << ' ' << y << '\n'; return 0; } وستكون ابنتيجة كالتالي: 0 9 1 8 2 7 3 6 4 5 5 4 6 3 7 2 8 1 9 0 أما بالنسبة لطباعة المتغير فيمكنك ببساطة إستخدام المعامل >> مرتين أو أكثر، على النحو التالي: int x{ 1 }; int y{ 2 }; std::cout << ++x << ' ' << ++y << '\n';
    1 نقطة
  23. يمكنك القيام بهذا الأمر بعدة طرق، كالتالي: تحويل قيمة المتغير age إلى نص من خلال الدالة to_string: int age = 18; std::string name = "Mohammed"; std::string new_name = "Your name is " + name + " and your age is " + std::to_string(age); std::cout << new_name; // Your name is Mohammed and your age is 18 أو إن كنت تستعمل مكتبة boost فيمكنك أن تستعمل التابع int_to_string: int age = 18; std::string name = "Mohammed"; std::string new_name = "Your name is " + name + " and your age is " + boost::lexical_cast<std::string>(age); std::cout << new_name; // Your name is Mohammed and your age is 18 تستطيع أيضًا أن تستعمل stringstream، على النحو التالي: // لإستخدام stringstream #include <sstream> int age = 18; std::string name = "Mohammed"; std::stringstream ss; ss << age; std::string new_name = "Your name is " + name + " and your age is " + ss.str(); std::cout << new_name; // Your name is Mohammed and your age is 18
    1 نقطة
  24. يمكنك أن تقوم بتعديل الدالة globl لكي تقوم بالبحث عن كل الملفات التي لديها الصيغة jpg أو png أو gif كالتالي: // غير السطر التالي $stored_imgs =glob($targetDirectory."*.jpg"); // إلى هذا السطر $stored_imgs = glob($targetDirectory."*.{jpg,png,gif}", GLOB_BRACE); بهذه الطريقة سوف يتم التطبيق على كل الصور التي لديها الصيغة jpg أو png أو gif.
    1 نقطة
  25. يُمكن بيع القوالب الجاهزة في خمسات، فعند البحث عن كلمة "قالب" على سبيل المثال، ستجد خدمات تقوم ببيع قالب معين مع بعض الإضافات والمميزات المدفوعة والإختيارية مثل بيع القالب بدون حقوق أو تركيبة على أكثر من مدونة. ويمكنك أن تقوم بعمل خدمة في خمسات وسيتم مراجعتها من قِبل فريق مختص، وإن حدثت مشكلة أو كانت الخدمة مخالفة سوف يتم الرد عليك من خلال البريد الإلكتروني بكل التفاصيل وهذا الأمر مذكور في نهاية صفحة المساعدة "إضافة خدمة مميزة". يمكنك أيضًا أن تقوم بإعطاء المستخدم شرح بسيط عن كيفية إستخدام القالب ومميزاته في شكل كُتيب صغير أو مقطع فيديو. نصيحة إضافية: قُم بقراءة بعض المقالات من الأكاديمية حول إستخدام برنامج Microsoft Word، وهذا الأمر سيساعدك للغاية في تحسين القوالب التي تقوم بها وإضافة بعض المميزات إليها.
    1 نقطة
  26. يمكنك أن تستخدم الأمر التالي في مشروعك (تأكد أنك في مجلد المشروع الصحيح): git remote set-url origin https://<access-token>@github.com/<username>/<repo> قم بوضع الـ access token واسم المستخدم واسم المستودع أيضًا.
    1 نقطة
  27. بداية من شهر أغسطس الماضي لم يعد تسجيل الدخول عبر 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.
    1 نقطة
  28. يمكنك إضافة عمود لجدول موجود بالفعل من خلال الصيغة التالية: 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 - موسوعة حسوب).
    1 نقطة
  29. لا تقرأ المتصفحات فعليًا الملف الذي يتم تحديده وإنما يتم تحديد نوع الملف بناءً على امتداده (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; } }); });
    1 نقطة
  30. سنتعلّم في هذا الدرس: بناء هيكل تطبيق بسيط لشرح أفكار الدرس استخدام إطار العمل Bootstrap استخدام بنى معطيات متقدمة مع عناصر الإدخال النصية المعدِّلات (Modifiers) في Vue.js التعامل مع مربعات الاختيار (Checkboxes) وأزرار الانتقاء (Radiobuttons) التعامل مع القائمة المنسدلة <select> إرسال البيانات ‎ لقد تعاملنا في بداية هذه السلسلة مع عناصر الإدخال العادية التي يستخدمها المستخدم لإدخال البيانات ضمن صفحات الويب. سنعمل في هذا الدرس على التوسّع في التعامل مع هذه العناصر بالإضافة إلى الاطلاع على طريقة التعامل مع عناصر إدخال HTML جديدة. كما سنتعلّم كيفية التعامل مع أُطر عمل CSS جاهزة، حيث لم يسبق لنا التعامل معها مسبقًا. بناء هيكل تطبيق بسيط لشرح أفكار الدرس كما جرت العادة، سنبني تطبيق بسيط من أجل هذا الدرس بهدف تطبيق الأفكار الواردة فيه. سيتكوّن تطبيقنا من صفحة واحدة فقط تحوي عدد من عناصر HTML التي ننوي التعامل معها. أنشئ مشروع جديد وسمّه input-forms-cli كما فعلنا مسبقًا في الدرس السابق (راجع الفقرة "بناء هيكل تطبيق بسيط لشرح أفكار الدرس"). بعد الانتهاء من عملية الإنشاء، استخدم Visual Studio Code في فتح المشروع (المجلّد) الذي أنشأته توًّا. لن نحتاج سوى ملف مكوّن واحد وهو App.vue لذلك احذف الملف HelloWorld.vue كما فعلنا في الدرس السابق. ثم افتح الملف App.vue واستبدل المحتوى الحالي بالشيفرة البرمجية التالية: <template> <div class="container"> <form> <div class="row"> <div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3"> <h1 class="text-right">الملف الشخصي للمستخدم</h1> <hr> <div class="form-group"> <label class="float-right" for="firstname">الاسم</label> <input type="text" id="firstname" class="form-control" v-model="userMainData.firstname"> </div> <div class="form-group"> <label class="float-right" for="lastname">الكنية</label> <input type="text" id="lastname" class="form-control" v-model="userMainData.lastname"> </div> <div class="form-group"> <label class="float-right" for="age">العمر</label> <input type="number" id="age" class="form-control" v-model="userMainData.age"> </div> <div class="form-group"> <label class="float-right" for="password">كلمة المرور</label> <input type="password" id="password" class="form-control" v-model="userMainData.password"> </div> </div> </div> <div class="row"> <div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 form-group"> <label class="float-right" for="description">نبذة</label><br> <textarea id="description" rows="5" class="form-control" v-model="description"></textarea> </div> </div> <div class="row"> <div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3"> <div class="form-group"> <label class="float-right" for="graduate"> <input type="checkbox" id="graduate" value="متخرج" v-model="status"> متخرج </label> <label class="float-right" for="smoker"> <input type="checkbox" id="working" value="أعمل حاليًا" v-model="status"> أعمل حاليًا </label> </div> </div> </div> <div class="row"> <div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 form-group"> <label class="float-right" for="male"> <input type="radio" id="male" value="ذكر" v-model="gender"> <span>ذكر</span> </label> <label class="float-right" for="female"> <input type="radio" id="female" value="أنثى" v-model="gender"> <span>أنثى</span> </label> </div> </div> <div class="row"> <div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 from-group"> <label class="float-right" for="subscriptionKind">نوع الاشتراك</label> <select id="subscriptionKind" class="form-control" v-model="selectedSubscription"> <option v-for="kind in subscriptionKinds" v-bind:key="kind"> {{ kind }} </option> </select> </div> </div> <hr> <div class="row"> <div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-1"> <button class="btn btn-primary">إرسال </button> </div> </div> </form> <hr> <div class="row"> <div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3"> <div class="card card-info"> <div class="card-header text-right"> <h4>البيانات المُدخلة</h4> </div> <div class="card-body"> <div class="card-text text-right"> <p>الاسم:{{ userMainData.firstname }}</p> <p>الكنية:{{ userMainData.lastname }}</p> <p>العمر:{{ userMainData.age }}</p> <p>كلمة المرور:{{ userMainData.password }}</p> <p>نبذة: {{ description }}</p> <p><strong>الوضع الحالي</strong></p> <ul> <li v-for="item in status" v-bind:key="item">{{ item }}</li> </ul> <p>النوع:{{ gender }}</p> <p>نوع الاشتراك: {{ selectedSubscription }}</p> </div> </div> </div> </div> </div> </div> </template> <script> export default { data() { return { userMainData: { firstname: '', lastname: '', age: 0, password: '', }, description: 'اكتب نبذة قصيرة عنك!', status: [], gender: 'ذكر', selectedSubscription: 'فضي', subscriptionKinds: ['ذهبي', 'فضي', 'عادي'] } } } </script> <style> @import "./assets/styles/app.css"; </style> أضف مجلّدًا جديدًا ضمن المجلّد assets وسمّه styles ثم أضف ملفًا جديدًا ضمن المجلّد الأخير وسمّه app.css كما فعلنا في الدرس السابق. احرص أن تكون محتويات الملف app.css على الشكل التالي: @import url(//fonts.googleapis.com/earlyaccess/notonaskharabic.css); body{ font-family: 'Noto Naskh Arabic', serif; } احفظ جميع التعديلات، ثم افتح موجّه الأوامر في ويندوز، وبعدها انتقل إلى مجلد التطبيق input-forms-cli الذي أنشأته قبل قليل، ونفّذ الأمر: npm run serve يعمل هذا الأمر كما نعلم على تشغيل خادوم الويب الخاص بالتطوير، اذهب الآن إلى متصفح الويب لديك، وانتقل إلى العنوان http://localhost:8080/ ليظهر لك شكل شبيه بما يلي: استخدام إطار العمل Bootstrap ربما تكون قد استغربت قليلًا من عدم استخدامنا لأي مكتبة أو إطار عمل CSS في عمليات التنسيق التي كنا نجريها في تطبيقاتنا السابقة. بدلًا عن ذلك، كنا نستخدم شيفرة CSS عادية فحسب في تنسيق التطبيقات. يعود سبب ذلك إلى أنّه لا يُنصح أبدًا إضافة إطار عمل CSS بالطريقة التقليدية التي تتمثل في استخدام الوسم <link> كما يفعل أغلبنا عند تطوير تطبيقات أمامية (Frontend Applications). يعود السبب في ذلك لأنّ أغلب أُطر عمل CSS تحتوي على شيفرة JavaScript قد لا تكون متوافقة مع Vue.js. علينا إذًا استخدام إطار عمل CSS نضمن أن يكون متوافقًا مع Vue.js لكي لا تحصل مفاجآت غير مرغوبة! سأتحدث هنا عن استخدام إطار العمل الشهير Bootstrap لكي نُكسب تطبيقاتنا تنسيقات جميلة وقوية وبشكل متوافق مع Vue.js. افتح نافذة موجه الأوامر في ويندوز، ثم نفّذ الأمر التالي: npm install bootstrap@4.0.0 بعد الانتهاء وعودة موجه الأوامر إلى حالته الطبيعية، أضف السطر التالي إلى الملف main.js: import "bootstrap/dist/css/bootstrap.min.css"; ستصبح محتويات الملف main.js مشابهة لما يلي: import Vue from 'vue' import App from './App.vue' Vue.config.productionTip = false import "bootstrap/dist/css/bootstrap.min.css"; new Vue({ render: h => h(App), }).$mount('#app') نكون بهذا الشكل قد نصبنا إطار العمل Bootstrap ومن ثمّ أضفناه إلى التطبيق الخاص بنا ليصبح جاهزًا للاستخدام. وهكذا نكون قد استغنينا عن كتابة تنسيقات مخصّصة إلى حد كبير. استخدام بنى معطيات متقدمة مع عناصر الإدخال النصية في الحقيقة رغم أنّ عنوان هذه الفقرة مغرٍ بعض الشيء، إلّا أنّنا في الواقع سنستخدم كائن JavaScript عادي لتمثيل بيانات المستخدم الأساسية ضمن تطبيقنا الحالي. إذا راجعت شيفرة التطبيق الأساسية التي أوردتها في الفقرة الأولى، وتحديدًا ضمن القسم <script> ستجد البنية البسيطة التالية: userMainData:{ firstname:'', lastname:'', age:0, password:'', } كما أوضحت، سيحمل الحقل userMainData بيانات المستخدم الرئيسية التالية على الترتيب: الاسم، الكنية، العمر، كلمة المرور. السؤال هنا، كيف سنربط عناصر HTML الموافقة؟ الجواب بسيط، سنستخدم v-model للربط ثنائي الاتجاه. انظر إلى الشيفرة المقتطعة من الشيفرة الموجودة ضمن القسم <template>: <div class="form-group"> <label class="float-right" for="firstname">الاسم</label> <input type="text" id="firstname" class="form-control" v-model="userMainData.firstname"> </div> <div class="form-group"> <label class="float-right" for="lastname">الكنية</label> <input type="text" id="lastname" class="form-control" v-model="userMainData.lastname"> </div> <div class="form-group"> <label class="float-right" for="age">العمر</label> <input type="number" id="age" class="form-control" v-model="userMainData.age"> </div> <div class="form-group"> <label class="float-right" for="password">كلمة المرور</label> <input type="password" id="password" class="form-control" v-model="userMainData.password"> </div> لاحظ معي كيف استخدمت الحقل userMainData لربط كل خاصية من خصائصه بعنصر HTML الموافق. انظر مثلًا ماذا استخدمت لربط حقل الاسم firstname: userMainData.firstname لقد استخدمت النقطة للفصل بين userMainData وبين firstname وهذا جائز تمامًا! يمكنك مراجعة باقي عناصر HTML لترى كيف استخدمت نفس الترميز السابق. الفائدة في استخدام هذا الأسلوب هي في تنظيم وتمثيل البيانات بشكل منطقي في التطبيق. حاول كتابة أي شيء ضمن الحقول الأربعة السابقة، ستجد أنّ ذلك سينعكس مباشرة على القسم السفلي (البيانات المُدخلة) من الصفحة، والذي جعلته خصيصًا لمشاهدة النتائج التي سنجريها على البيانات في القسم العلوي. في الحقيقة لقد تعاملنا مسبقًا مع عناصر الإدخال العادية فيما سبق من دروس، وسنتعامل مع أنواع أخرى من عناصر الإدخال في هذا الدرس. أحد العناصر الجديدة التي سنتعامل معها هو العنصر <textarea> والذي نتعامل معه كما نتعامل مع عناصر الإدخال العادية تمامًا. إذ وضعت الموجّه v-model ضمن هذا العنصر ليرتبط مع الحقل description كما هو واضح من الشيفرة الواردة في الفقرة الأولى من هذا الدرس. المُعدِّلات (Modifiers) في Vue.js يحتاج المبرمج في بعض الأحيان إلى تعديل سلوك الاستجابة لـ Vue.js. فمثلًا إذا لاحظت في تطبيقنا هذا، أنّ أي شيء تكتبه ضمن أي عنصر من عناصر الإدخال النصية، سينعكس مباشرة ضمن القسم السفلي. قد يكون هذا السلوك غير مرغوب أحيانًا، فقد ترغب ربما بأن لا يستجيب Vue.js مباشرةً لما يكتبه المستخدم، بل بأن تؤجّل هذه الاستجابة حتى ينتهي المستخدم مما يكتبه وينتقل إلى حقل نصي آخر مثلًا. السيناريو السابق ممكن تمامًا باستخدام تقنية المعدِّلات (modifiers) حيث يمكن أن نستخدم المعدِّل lazy لكي نخبر Vue.js بأن يؤجّل الاستجابة لأي عنصر إدخال مرتبط معه ريثما يعمل المستخدم على مغادرة هذا العنصر (يُفقده التركيز Focus). انتقل إلى الشيفرة البرمجية الخاصة بعنصر الإدخال firstname ضمن <template> ثم أضف المعدّل lazy إلى الموجّه v-model على الشكل التالي: v-model.lazy="userMainData.firstname" احفظ التغييرات، ثم حاول كتابة شيء ما ضمن الحقل firstname ولا تحاول مغادرة الحقل، ستجد هذه المرة أنّ ذلك لن ينعكس مباشرة ضمن القسم السفلي. غادر الآن ذلك الحقل إلى حقل آخر، ستجد أنّ بيانات الاسم قد ظهرت دفعة واحدة في القسم السفلي. توجد معدّلات أخرى مثل number الذي يُستخدم لكي يُفسَّر دخل المستخدم على أنّه رقم بدلًا من النص. وهناك أيضًا المعدّل trim الذي يُستخدم للتخلص من المحارف الفارغة على يمين ويسار النص المُدخَل. يمكن استخدام أي معدّل كما استخدمنا المعدّل lazy قبل قليل، كما ويمكن استخدامها بشكل مركّب. انظر مثلًا كيف يمكن استخدام المعدلين lazy و trim بشكل مركّب: v-model.lazy.trim = "userMainData.firstname" التعامل مع مربعات الاختيار (Checkboxes) وأزرار الانتقاء (Radiobuttons) سنتعلّم في هذه الفقرة كيفية التعامل مع مربع الاختيار (Checkbox) وزر الانتقاء (Radiobutton). سنبدأ أولًا مع مربع الاختيار. في تطبيقنا هذا، سنستخدم مربّعي اختيار للتعبير عن كون المستخدم متخرّج أم غير متخرّج. بهدف التعامل مع هذين المربعين، عرّفت حقلًا جديدًا اسمه status على أنّه مصفوفة (انظر القسم <script>). ربطت هذه المصفوفة مع مربعي الاختيار بإسنادها إلى الموجّه v-model لكل من المربعين. انظر الشيفرة المقتطعة من القسم <template>: <label class="float-right" for="graduate"> <input type="checkbox" id="graduate" value="متخرج" v-model="status"> متخرج </label> <label class="float-right" for="smoker"> <input type="checkbox" id="working" value="أعمل حاليًا" v-model="status"> أعمل حاليًا </label> لاحظ كيف أنّنا ربطنا مربعي الاختيار بنفس الشكل. الذي سيحدث وراء الكواليس، هو أنّه عندما يختار المستخدم أحد المربّعين سيعمل Vue.js على إدراج قيمة الحقل الذي تمّ اختياره كعنصر في المصفوفة status، فإذا اختار المستخدم كلا المربعين، فسيدرج Vue.js عنصرين ضمن المصفوفة، يعبّر كل منهما عن قيمة مربّع الاختيار. أي أنّ عدد عناصر المصفوفة سيكون مساويًا لعدد المربعات التي اختارها المستخدم، طالما أنّ هذه المربعات قد تمّ ربطها بنفس الشكل. يمكن تطبيق نفس المبدأ تقريبًا على أزرار الانتقاء، في تطبيقنا هذا لدينا زري انتقاء يُعبّران عن نوع المستخدم (ذكر أم أنثى). عرّفت حقلًا جديدًا أسميته gender يحمل القيمة الافتراضية ذكر. انظر معي إلى الشيفرة المقتطعة من القسم <template> لزري الانتقاء: <label class="float-right" for="male"> <input type="radio" id="male" value="ذكر" v-model="gender"> <span>ذكر</span> </label> <label class="float-right" for="female"> <input type="radio" id="female" value="أنثى" v-model="gender"> <span>أنثى</span> </label> لاحظ معي بدايةً أنّني قد وضعت القيمة value لكل من الزرين السابقين لتكونا ذكر و أنثى على الترتيب. لاحظ أيضًا كيف استخدمت نفس أسلوب الربط باستخدام الموجّه v-model لكل من هذين الزرين. الذي سيحدث عند بدء تشغيل التطبيق أنّ الحقل gender سيحمل القيمة ذكر بشكل افتراضي كما ذكرت قبل قليل، وبالتالي سيختار Vue.js الزر المعبّر عن الـ "ذكر" لأنّ قيمته ستكون مماثلة لقيمة الحقل gender في هذه الحالة. وهذا ما يبرّر الاختيار الافتراضي لهذا الزر عند البدء بتشغيل التطبيق. جرب أن تجري الآن بعض التجارب على مربعي الاختيار وزري الانتقاء، ولاحظ النتائج التي ستحدث ضمن القسم السفلي المخصّص لعرض البيانات. التعامل مع القائمة المنسدلة <select> بقي لنا أن نتعلّم كيفية الربط مع القائمة المنسدلة <select>. سينقسم عملنا هنا إلى قسمين. الأوّل هو تعبئة هذه القائمة، والثاني هو الربط مع Vue.js باستخدام الموجّه v-model. بالنسبة لتعبئة هذه القائمة بالبيانات الأولية التي سيختار منها المستخدم، فقد عرّفت الحقل subscriptionKinds وهو على شكل مصفوفة تحوي العناصر التالية: subscriptionKinds: ['ذهبي', 'فضي', 'عادي'] تعبّر هذه المصفوفة عن نوع الاشتراك الذي يرغب المستخدم باعتماده. سيكون لدينا كما هو واضح ثلاثة اشتراكات. الشيفرة البرمجية المسؤولة عن تعبئة عنصر القائمة هي التالية: <option v-for="kind in subscriptionKinds" v-bind:key="kind"> {{ kind }} </option> هذه الشيفرة مأخوذة من القسم <template> بالطبع. وهي عبارة عن حلقة بسيطة تعمل على تعبئة القائمة من خلال توليد عناصر <option> العمود الفقري لعنصر القائمة <select>. بالنسبة لعملية الربط فقد عرّفت حقلًا آخرًا أسميته selectedSubscription وأسندت له القيمة الافتراضية فضي. لاحظ معي أنّ هذه القيمة مماثلة للعنصر الثاني من عناصر المصفوفة subscriptionKinds. بعد ذلك، ربطت عنصر القائمة باستخدام v-model على النحو التالي: v-model="selectedSubscription" وهكذا وعند تشغيل التطبيق للمرة الأولى، سيظهر العنصر الثاني فضي وقد اختير بشكل افتراضي. جرب الآن أن تغير خياراتك ضمن القائمة وانظر كيف سينعكس ذلك ضمن القسم السفلي المخصّص لعرض البيانات. إرسال البيانات كما هو معلوم، عند وضع عنصر الزر button ضمن عنصر النموذج form، فسيؤدي نقر هذا الزر إلى إرسال بيانات النموذج (form) إلى الخادوم. في تطبيقنا البسيط هذا، وضعنا زرًا لإرسال البيانات كما تعلم، ولكن بما أنّه ليس لدينا حاليًا أي تطبيق يعمل على الخادوم لمعالجة لبيانات المرسلة، لذلك سنعمل على معالجة البيانات محليًّا بشكل وهمي، لذلك سنغيّر من سلوك هذا الزر لكي نمنعه من التصرف بالشكل الافتراضي. سنستخدم لهذه الغاية المعدِّل prevent مع الموجّه v-on:click. اعمل على تعديل شيفرة HTML الخاصة بزر الإرسال لتصبح على النحو التالي: <button v-on:click.prevent="submitInfo" class="btn btn-primary">إرسال </button> سنضيف القسم method لكي نتمكّن من تعريف التابع submitInfo. سأضع هنا كامل قسم <script> بعد التعديل: methods:{ submitInfo(){ alert("تمت معالجة البيانات"); } } وضعت رسالة بسيطة تشير إلى أنّ البيانات قد تمت معالجتها بشكل افتراضي محليًّا. يمكن أن تضع بدلًا من هذه الرسالة أن شيفرة قد تجدها مناسبة للبيانات التي أدخلها المستخدم. الهدف هنا هو أن تفهم المبدأ بحيث يمكنك تكييفه فيما بعد بحسب احتياجاتك. ختامًا تعلّمنا في هذا الدرس كيفية استخدام أُطر عمل جاهزة لتنسيق المحتوى، حيث استخدمنا في هذا الدرس إطار العمل الشهير Bootstrap. كما تعلّمنا كيف نتعامل مع عدد من عناصر HTML المخصّصة لاستقبال الدخل من المستخدم، حيث تعاملنا مع عناصر الإدخال النصية البسيطة بالإضافة إلى عنصر الإدخال ذو الأسطر المتعدّدة <textarea> وأيضًا مربعات الاختيار وأزرار الانتقاء وعنصر القائمة المنسدلة. في الحقيقة، يمكن أن تبني عناصر إدخال مخصّصة بك وفق احتياجاتك الخاصة وذلك باستخدام المكوّنات كما مرّ معنا في دروس سابقة. أرجو لك الفائدة من هذا الدرس، أراك في الدروس القادمة إن شاء الله. اقرأ أيضًا المقال التالي: المرشحات Filters والـمخاليط Mixins في Vue.js المقال السابق: إنشاء مشاريع Vue.js باستخدام Vue CLI النسخة الكاملة لكتاب أساسيات إطار العمل Vue.js
    1 نقطة
  31. Composer هو أداة لإدارة الاعتماديات في لغة PHP، تخيل أنّك تعمل على مشروع يتضمن العديد من الاعتماديات التابعة لمشاريع أو مكتبات أخرى. سيدير Composer بالطرق التالية: تحميل مكتبة الاعتمادية من مستودعاتها إلى مشروعك بصورة تلقائية. يمكنك وبكلّ سهولة تحديث مكتبتك عند ظهور إصدار جديد منها. عند تحميل مكتبة الاعتمادية يتحقّق composer من المتطلبات الدنيا للخادوم. سينشئ Composer ملف autoloader.php لجميع المكتبات المحمّلة وسيحمّل الاعتمادية كاملةً في المشروع الذي تعمل عليه. ماذا سيحصل إن لم تستخدم Composer؟ ستضطرّ إلى تحميل مكتبة الاعتمادية يدويًّا. يجب عليك التحقّق من الإصدارات الجديدة للمكتبات دوريًّا، وتحميل الملفات إلى المشروع يدويًّا. يجب عليك تحميل جميع المكتبات إلى مشروعك باستخدام دالتي require أو include. إليك المثال التالي لتوضيح ما سبق: لديك مشروع تعمل عليه باستخدام إطار عمل Cakephp أو Laravel، وترغب في إضافة خاصية إرسال الرسائل إلكترونية إلى المشروع وتحتاج إلى اتصال من نوع SMTP. ستقوم حينها بتحميل إحدى المكتبات المتخصّصة في هذا المجال مثل Phpmailer أو Swiftmailer. إن استخدمت composer للحصول على هذا المكتبات، فسيكون بميسورك تحميل المكتبة المطلوبة مباشرة إلى مجلد vendor ضمن المشروع. وإن حصلت هذه المكتبة على تحديث جديد، يكفي أن تنفّذ أمرًا واحدًا في سطر الأوامر، ولن تكون بحاجة إلى التحقّق ممّا إذا كان التحديث متوافقًا مع الإصدار 5.4 أو 5.3 من php. سيتّضح الأمر أكثر فأكثر من خلال الأمثلة التالية. كيف يتم تثبيت Composer في النظام قبل تثبيت composer يجب التحقّق من أنّك تعمل على الإصدار 5.4 وما بعده من لغة PHP. إن كنت من مستخدمي نظام ويندوز فيمكنك تحميل الملف التنفيذي الخاص بتثبيت Composer وذلك من الرابط: https://getcomposer.org/، وتنصيب Composer في نفس المجلد الذي قمت بتثبيت php.exe فيه. (C:\wamp\bin\php\php5.5.12 مثلاً). أما مستخدمو نظامي Linux و Mac فيمكنهم فتح الطرفية وكتابة الأمر التالي فيها: curl -sS https://getcomposer.org/installer | php سيقوم هذا الأمر بتحميل ملف composer.phar (phar تعني php archive) بواسطة الأداة curl، وللوصول إلى composer من أي مكان في حاسوبك يجب عليك نقل هذا الملف إلى المجلد /usr/bin/composer، وذلك بتنفيذ الأمر التالي في الطرفية: sudo mv composer.phar /usr/bin/composer للتحقق من وجود Composer يكفي الدخول إلى سطر الأوامر في ويندوز أو الطرفية في Linux و Mac وكتابة كلمة composer والضغط على زر الإدخال Enter. إن كان Composer مثبّتًا في جهازك ستظهر شاشة الترحيب التالية إضافة إلى جميع ا لأوامر المستخدمة في composer. تطبيق عملي لاستخدام مكتبة Composer سيبحث Composer عن الملف composer.json حيث سندرج جميع الاعتماديات التي نحتاج إليها في المشروع. لننشئ مجلّدًا جديدًا بواسطة الأمر التالي: mkdir composer_example ادخل إلى المجلد: cd composer_example أنشئ ملف composer.json هنا، وأضف إليه ما يلي: { "require": { "jdorn/sql-formatter": "1.3.*@dev" } } هنا jdorn هو اسم صاحب الحزمة sql-formatter التي نرغب في تثبيتها ضمن المشروع. ولكن قد تتسائل من أين سيأتي Composer بهذه الحزمة. في الواقع هناك موقع إلكتروني آخر هو Packagist يتضمّن جميع المكتبات الشائعة ويمكن تصفّحها من خلال الموقع. مكتبة sql-formatter عبارة عن صنف php صغير الحجم يعمل على تنسيق عبارات SQL حيث يضبط الإزاحات في بداية العبارة تلقائيًا كما يدعم تلوين الكلمات المفتاحية. بعد أن أعددنا ملف composer.json يمكننا تحميل وتنصيب الملفات المطلوبة في مجلد المشروع بواسطة الأمر: composer install سيتم تحميل جميع الملفات المطلوبة ومن ضمنها ملفات autoload إلى المجلد composer_example/vendor. والآن أنشئ ملفًّا باسم index.php في المجلد composer_example واجلب فيه الملف autoload.php باستخدام الدالة require وبذلك سيتمّ تحميل جميع الاعتماديات في هذا الملف. إليك المثال التالي: <?php require "vendor/autoload.php"; $query = "SELECT count(*),`Column1`,`Testing`, `Testing Three` FROM `Table1` WHERE Column1 = 'testing' AND ( (`Column2` = `Column3` OR Column4 >= NOW()) ) GROUP BY Column1 ORDER BY Column3 DESC LIMIT 5,10"; echo SqlFormatter::format($query); ?> لاحظ مدى سهولة وسرعة التعامل مع الاعتماديات بواسطة Composer. لننشئ مشروعًا آخر لنفترض أننا نرغب في إضافة إطار عمل Codeigniter بواسطة Composer. لن نستخدم هذه المرّة الأمر composer install بل سنستخدم الأمر composer create-project لإنشاء مشروع جديد. توجّه إلى موقع Packagist وابحث عن مكتبة Codeigniter، ثم حمّل نسخة من إطار العمل إلى مجلد المشروع الذي تعمل عليه: composer create-project codeigniter/framework مجلد المشروع بعد اكتمال العملية ستجد ملف composer.json في مجلد المشروع، ويمكن إضافة المزيد من الاعتماديات إلى مشروعك بواسطة هذا الملف. لنفترض أنّك ترغب في استخدام حزمة sql-formatter في مشروعك هذا. توجّه إلى ملف composer.json وعدّله ليصبح بالصورة التالية: { "description" : "A way to install CodeIgniter via composer", "name" : "rogeriopradoj/codeigniter", "license": "OSL-3.0", "require": { "php": ">=5.2.4", "jdorn/sql-formatter": "1.3.*@dev" } } ثمّ حدّث الاعتماديات بواسطة الأمر: composer update والآن إن كنت ترغب في رفع هذا المشروع إلى Github أو مشاركته مع أحد الأصدقاء، لن تكون بحاجة إلى إرسال مجلد vendor، بل يكفي أن ترسل الملف composer.json وسيكون بميسور صديقك تحميل جميع الاعتماديات المطلوبة والمستخدمة في المشروع. عليك بتجربة composer، إذ تستخدمه معظم أطر عمل php المعروفة مثل Laravel، Symfony 2 و Yii إضافة إلى بعض حزم php الرائعة التابعة لـ Phpleague. فماذا تنتظر إذًا؟ ترجمة - وبتصرّف - للمقال Composer easy tutorial – php dependency management tool لصاحبه Arkaprava Majumder.
    1 نقطة
×
×
  • أضف...