كيفية إنشاء صفحة التسجيل الخاصة بك في WordPress Multisite. قم بإرسال النموذج دون إعادة التحميل باستخدام تسجيل الدخول باستخدام jQuery AJAX Infinite php lang

لدي صفحة تسجيل رئيسية ترسل البيانات إلى قاعدة بيانات SQL. ومع ذلك ، أود ألا يتم إعادة توجيه الصفحة عند الإرسال (سواء بنجاح أم لا).

هذا ما لدي حاليًا وهو لا يعمل. لا يعرض رسائل الخطأ.

HTML - signup.html

اشتراك

جافا سكريبت - signup.js

إرسال الوظيفة () ($ ("النموذج"). إرسال (الوظيفة (هـ) (e.preventDefault () ؛ $. ((النوع: "POST" ، url: "الاشتراك." ، البيانات: $ ("النموذج")) .serialize ()، Success: function () (console.log ("كان التسجيل ناجحًا") ؛) خطأ: function () (console.log ("كان التسجيل غير ناجح") ؛))) ؛) $ (مستند). جاهز (وظيفة () (إرسال () ؛)) ؛

PHP - signup.php

الاستعلام ($ addData) === TRUE) (echo "Working"؛) else (echo "Not working" ؛)؟>

هنا JSFiddle.

أتمنى أن تساعدوا يا رفاق. شكرا مقدما 🙂

إذا كنت تستخدم ajax ، فلن تحتاج إلى استخدام نوع الإدخال كزر إرسال.

$ (document) .ready (الوظيفة () ($ ("# signup"). انقر (الوظيفة (e) (e.preventDefault () ؛ $ .ajax ((النوع: "POST" ، url: "signup.php" ، data: $ ("form"). serialize () success: function () (console.log ("كان الاشتراك ناجحًا") ؛) خطأ: function () (console.log ("كان التسجيل غير ناجح") ؛)) ) ؛)) ؛

يتغير هنا أيضًا

$ post_FirstName = $ _POST ["first"] ؛ // الاسم هو "الأول" وليس "الاسم الأول"

لديك عدة مكابح وأقواس مغلقة بشكل غير صحيح

إرسال الوظيفة () ($ ("النموذج"). إرسال (الوظيفة (e) (e.preventDefault () ؛ $ .ajax ((النوع: "POST" ، url: "signup.php" ، البيانات: $ ("النموذج ") .serialize ()، Success: function () (console.log (" كان الاشتراك ناجحًا ") ؛) ، // هنا خطأ: function () (console.log (" كان التسجيل غير ناجح ") ؛))) ؛ )) ؛ // هنا) $ (المستند). جاهز (الوظيفة () (إرسال () ؛)) ؛

ليست هناك حاجة لاستدعاء وظيفة الإرسال. هذا فقط سيتم القيام به (لقد فاتتك الفاصلة وعلامة الإغلاق):

نخلق الصفحة الخاصةالتسجيل في مواقع متعددة بدلاً من ملف wp-signup.php القياسي.

في تثبيت WordPress نموذجي ، تعرض صفحة التسجيل (تسجيل الدخول ، إعادة تعيين كلمة المرور) ملف wp-login.php.

  • /wp-login.php - إذن
  • /wp-login.php؟action=register - التسجيل
  • /wp-login.php؟action=lostpassword - إعادة تعيين كلمة المرور

توجد شروط منفصلة للمواقع المتعددة في ملف wp-login.php. لذلك ، عند النقر فوق الرابط /wp-login.php؟action=register في موقع متعدد المواقع ، سيعيد WordPress التوجيه إلى صفحة /wp-signup.php. في العديد من المظاهر ، لا تبدو الصفحة جذابة للغاية ، لذلك سنقوم بتصميم الصفحة الخاصة بنا.

الموقع الرئيسي للشبكة

بشكل افتراضي ، يفتح WordPress صفحة تسجيل (wp-signup.php) على المجال الرئيسي (الموقع) للشبكة. ومع ذلك ، يمكنك إنشاء صفحة تسجيل منفصلة لكل موقع على الشبكة ، حتى لو كان لديهم سمات مختلفة. سننظر في الحالة عندما يكون لجميع المواقع على الشبكة صفحة تسجيل خاصة بها ، ولكن يتم استخدام نفس الموضوع وتختلف المواقع في اللغة فقط. إذا كنت تستخدم سمات مختلفة ، فستحتاج إلى كتابة المزيد من التعليمات البرمجية.

وظائف. php؟

لا. يبدو أن اسم هذا الملف مذكور في كل مقالة من WordPress. في حالتنا ، نظرًا لأن وظيفة التسجيل مصممة للعديد من المواقع ، فمن المنطقي نقلها إلى مكونات MU الإضافية التي يتم تحميلها عند فتح أي موقع.

استطرادا غنائي

من الجدير بالذكر أن ملحقات MU يتم تحميلها في وقت أبكر من الإضافات العادية وقبل تحميل نواة WordPress بالكامل ، لذا فإن استدعاء بعض الوظائف يمكن أن يؤدي إلى أخطاء فادحة في PHP. هذا التحميل "المبكر" له مزاياه أيضًا. على سبيل المثال ، داخل أي سمة ، لا يمكنك التمسك ببعض الإجراءات التي تم تشغيلها حتى قبل تحميل ملف function.php من السمة. مثال على ذلك هو الإجراءات من البرنامج المساعد Jetpack للنموذج jetpack_module_loaded_related-posts (ذات الصلة - اسم الوحدة) والتي يمكن من خلالها تتبع نشاط الوحدات في Jetpack. من المستحيل "التشبث" بهذا الإجراء من ملف السمة ، لأن الإجراء قد تم تشغيله بالفعل قبل تحميل السمة - يتم تحميل الإضافات قبل السمات. يمكنك إلقاء نظرة على صورة عامة لترتيب تحميل WordPress في صفحة مرجع الإجراء في المخطوطة.

ترتيب الملف

يمكن أن تحتوي ملحقات MU على أي عدد من الملفات وأي بنية تبدو منطقية بالنسبة لك. أنا متمسك بشيء مثل هذا التسلسل الهرمي:

| -mu-plugins | - | -load.php | - | - |-سيلينا-شبكة | - | - | - | -تسجيل | - | - | - | - | -plugin.php | - | - | - | - | -... | - | - | - | -jetpack | - | - | - | - | -plugin.php

جميع "المكونات الإضافية" الضرورية لشبكتنا متصلة في ملف load.php:

// تحميل Traslates لجميع الوظائف الإضافية load_muplugin_textdomain ("selena_network"، "/ selena-network / languages ​​/") ؛ // يتطلب الاشتراك في الشبكة WPMU_PLUGIN_DIR. "/selena-network/signup/plugin.php" ؛ // تتطلب ملحقات أخرى // WPMU_PLUGIN_DIR ...

يتم تخزين مجلدات البرنامج المساعد داخل مجلد selena-network ، ولكل منها plugin.php الخاص به ، والذي نقوم بتضمينه في load.php. يمنحك هذا المرونة والقدرة على إيقاف تشغيل الأشياء وتشغيلها بسرعة.

عنوان صفحة التسجيل

لتحديد عنوان صفحة التسجيل ، يتم استخدام عامل التصفية wp_signup_location. يمكن العثور عليه داخل ملف wp-login.php وهو مسؤول عن إعادة التوجيه إلى wp-signup.php.

حالة "تسجيل": if (is_multisite ()) (wp_redirect (application_filters ("wp_signup_location"، network_site_url ("wp-signup.php"))) ؛ خروج ؛

دعنا نضيف وظيفتنا إلى mu-plugins / selena-network / signup / plugin.php ، والتي ستعيد عنوان صفحة التسجيل على الموقع الحالي:

الوظيفة selena_network_signup_page ($ url) (عودة home_url (). "/ Signup /" ؛) add_filter ("wp_signup_location"، "selena_network_signup_page"، 99) ؛

selena_network هي البادئة التي أستخدمها في أسماء جميع الوظائف داخل مكونات MU الإضافية على موقعي لتجنب الاصطدامات ، يجب استبدالها ببادتي الفريدة. المرشح له أولوية 99 لأن بعض المكونات الإضافية مثل bbPress و BuddyPress قد تستبدل عنوان URL هذا بعناوينها (يتم تحميل مكونات MU في وقت أبكر من المكونات الإضافية العادية ، انظر أعلاه). لاحظ أنه يتم استخدام home_url () بدلاً من network_site_url () لإبقاء الزائر في نفس المجال. يمكن استخدام أي عنوان URL كعنوان.

قم بإنشاء صفحة

لنقم الآن بإنشاء صفحة بالعنوان site.com/signup/ من خلال الواجهة المعتادة ، وفي مجلد السمة الفرعية القالب الخاص بنا صفحة جديدة- page-signup.php. يمكن استخدام معرّف فريد بدلاً من كلمة "اشتراك".

داخل القالب الجديد ، تحتاج إلى استدعاء دالة selena_network_signup_main () ، والتي ستعرض نموذج التسجيل.

وتجدر الإشارة إلى أن العملية بأكملها باستخدام القوالب غير مطلوبة وبدلاً من ذلك يمكنك إنشاء الرمز القصير الخاص بك ، والذي سيستدعي أيضًا وظيفة selena_network_signup_main ().

wp-signup.php و wp-active.php

لنبدأ الآن في إنشاء وظيفة ستعرض نموذج التسجيل. للقيام بذلك ، انسخ ملفي wp-signup.php و wp-active.php من جذر WordPress إلى mu-plugings / selena-network / signup / (ولا تنس توصيلها داخل mu-plugins / selena-network / signup / plugin.php) ... من الصعب للغاية وصف المزيد من التلاعبات بالملفات ويستغرق وصفها وقتًا طويلاً ، لذلك سيتعين عليك القيام بها بنفسك. سأصف فقط ما يجب القيام به بالضبط وأنشر الملفات المصدر لمشروعي:

  1. في بداية الملف ، قم بإزالة جميع الطلبات واستدعاءات الوظائف والرموز الأخرى خارج الوظائف.
  2. أعد تسمية جميع الوظائف عن طريق إضافة بادئات فريدة للأسماء.
  3. لف الجزء السفلي من كود wp-signup.php في دالة selena_network_signup_main واكتب $ active_signup العام في البداية ؛ ...
  4. استبدل التصميم بالتخطيط الخاص بك في الأماكن الصحيحة.

داخل ملف wp-active.php ، عليك أن تفعل الشيء نفسه تقريبًا:

  1. قم بإزالة جميع التعليمات البرمجية خارج الوظائف ، وقم بلف التخطيط في وظيفة منفصلة.
  2. قم بتغيير التخطيط عند الضرورة.

ملف wp-active.php مسؤول عن صفحة تنشيط الحساب. كما هو الحال مع صفحة التسجيل ، تحتاج إلى إنشاء قالب منفصل لها ، تقوم بداخله باستدعاء الوظيفة من ملف wp-active.php.

نرسل رسائل التفعيل

صفحة التسجيل ترسل إلى الزائر بريدًا إلكترونيًا به رابط لتفعيل حسابه. بشكل افتراضي ، يتم ذلك عن طريق وظيفة wpmu_signup_user_notification () من ملف ms-function.php. يمكن استعارة وظائفها من أجل وظيفتك. سبب التوقف عن استخدام هذه الميزة هو أنها ترسل رابط تنشيط الحساب من wp-active.php. يمكنك "تعطيل" هذه الوظيفة باستخدام مرشح wpmu_signup_user_notification ، وإعطاء خطأ (خطأ) (إذا لم تقم بذلك ، فسيتم إرسال خطاب التنشيط مرتين ، حسنًا ، في الواقع ، حرفان مختلفان).

الوظيفة armyofselenagomez_wpmu_signup_user_notification ($ user، $ user_email، $ key، $ meta = array ()) (// ... // Code from function wpmu_signup_user_notification () wp_mail ($ user_email، wp_specialchars_decode ($ message_headers) إرجاع خطأ ؛) add_filter ("wpmu_signup_user_notification"، "armyofselenagomez_wpmu_signup_user_notification"، 10، 4)؛

نتيجة لذلك ، تبدو صفحة التسجيل في موضوع سيلينا أنظف وأكثر دقة.

استنتاج

هناك العديد من الطرق الأخرى غير الصحيحة لفعل الشيء نفسه على الإنترنت - عمليات إعادة توجيه Apache ونماذج AJAX التي لن تعمل بدون Java Script وما إلى ذلك من موقع الويب الخاص بك.

لاحظ أنه يجب عليك تحرير الملفات بعناية ومحاولة عدم الانحراف كثيرًا عن الأصل ، بحيث إذا قام WordPress في المستقبل بتغيير ملفات wp-signup.php و wp-activ.php ، فسيكون من الأسهل مقارنتها للعثور على التغييرات.

لا تنسى أن تبحث في مصدرجميع الوظائف الموضحة أعلاه لفهم ما يحدث داخل الكود بشكل كامل وكيف.

علاوة. حماية مرسلي الرسائل الاقتحامية

حتى أصغر مواقع WordPress تخضع لعمليات تسجيل البريد العشوائي المتكررة. يمكنك كتابة شروط لا حصر لها لتصفية الروبوتات ، وغالبًا ما تكون أشبه بمحاولة الإنشاء الذكاء الاصطناعي🙂 في حالة المواقع المتعددة ، ساعدتني إعادة التوجيه المعتادة في Apache كثيرًا ، والتي عند فتح /wp-signup.php و /wp-acitvate.php ، طلبت 404 (لست خبيرًا في Apache التكوين ، لذلك قد لا تكون قواعدي صحيحة للغاية).

RewriteEngine On RewriteBase / RewriteRule ^ wp-signup \ .php - إعادة كتابة القاعدة ^ wp-active \ .php - # BEGIN WordPress # لا تلمس قواعد WordPress افتراضيًا :) # ... # END WordPress

P. S. أحاول أن أصف بأكبر قدر ممكن من التفاصيل بعض الأشياء الخاصة بالأطراف الثالثة ، لأنه عندما بدأت ، لم يكن هناك في بعض الأحيان من يطالب ويشرح الكثير من الأشياء. أعتقد أيضًا أن مثل هذه النصائح الصغيرة حول المواد الأخرى ستدفع الشخص لتعلم شيء جديد وتوسيع مجال معرفته. يتم استخدام التعبيرات العادية في إدخالات RewriteRule ، فهي ليست معقدة على الإطلاق ، على سبيل المثال ، يشير الحرف ^ إلى بداية السطر.

الإعلانات

تحتوي الكثير من مواقع الويب على نموذج تسجيل للمستخدمين للتسجيل ، وبالتالي قد يستفيدون من نوع من الامتياز داخل الموقع. سنرى في هذه المقالة كيفية إنشاء نموذج تسجيل في PHP و MySQL.

سنستخدم علامات بسيطة كما سنستخدم علامة الجدول لتصميم صفحة الويب Sign-Up.html. لنبدأ:

قائمة 1: sign-up.html

اشتراك

إستمارة تسجيل
اسم
بريد الالكتروني
اسم االمستخدم
كلمه السر
تأكيد كلمة المرور


شكل 1:

وصف صفحة ويب sing-in.html:

كما ترى في الشكل 1 ، يوجد نموذج تسجيل ويسأل عن بيانات قليلة عن المستخدم. هذه هي البيانات الشائعة التي يطلبها أي موقع ويب من مستخدميه أو زواره لإنشاء ومعرف وكلمة مرور. استخدمنا علامة الجدول لأنه لإظهار حقول النموذج على صفحة الويب في نموذج ترتيب كما يمكنك رؤيتها في الشكل 1. يبدو الأمر بسيطًا جدًا لأننا لم نستخدم نمط CSS عليه الآن ، فلنستخدم أنماط CSS ونربط ملف نمط CSS مع صفحة ويب sing-up.html.

القائمة 2: style.css

/ * ملف CSS لصفحة الويب الخاصة بالتسجيل * / # body-color (background-color: # 6699CC؛) # Sign-Up (background-image: url ("sign-up.png") ؛ حجم الخلفية: 500px 500px ؛ تكرار الخلفية: عدم التكرار ؛ مرفق الخلفية: ثابت ؛ موضع الخلفية: المركز ؛ الهامش العلوي: 150 بكسل ؛ الهامش السفلي: 150 بكسل ؛ الهامش الأيمن: 150 بكسل ؛ الهامش الأيسر: 450 بكسل ؛ الحشو: 9 بكسل 35 بكسل ؛ ) # زر (نصف قطر الحد: 10 بكسل ؛ العرض: 100 بكسل ؛ الارتفاع: 40 بكسل ؛ الخلفية: # FF00FF ؛ وزن الخط: غامق ؛ حجم الخط: 20 بكسل ؛)

قائمة 3: ربط style.css بصفحة الويب sign-up.html



الشكل 2:

وصف ملف style.css:

في ملف CSS الخارجي ، استخدمنا بعض الأنماط التي قد تبدو جديدة بالنسبة لك. حيث استخدمنا صورة في الخلفية وقمنا بتعيينها في وسط صفحة الويب. والتي أصبحت سهلة الاستخدام بمساعدة وسم html div. حيث استخدمنا ثلاثة معرفات لعلامة div. #button و # sing-up و # body-color وقمنا بتطبيق جميع أنماط CSS عليها والآن يمكنك رؤية الشكل 2 ، إلى أي مدى يبدو جميلًا وجذابًا. يمكنك استخدام العديد من أنماط CSS الأخرى مثل أنماط CSS ثنائية وثلاثية الأبعاد عليها. سيبدو أجمل من مظهره الآن.

بعد كل هذه الأعمال البسيطة ، سنقوم الآن بإنشاء قاعدة بيانات وجدول لتخزين جميع البيانات في قاعدة بيانات المستخدمين الجدد. قبل أن نبدأ في إنشاء جدول ، يجب أن نعرف أن ما نطلبه من المستخدم. أثناء قيامنا بتصميم النموذج ، سننشئ الجدول وفقًا لاستمارة التسجيل التي يمكنك رؤيتها في الشكل 1 و 2.

قائمة 3: الاستعلام عن الجدول في MySQL

إنشاء موقع ويب جدول المستخدمين (معرف المستخدم int (9) NOT NULL auto_increment ، الاسم الكامل VARCHAR (50) NOT NULL ، اسم المستخدم VARCHAR (40) NOT NULL ، البريد الإلكتروني VARCHAR (40) NOT NULL ، اجتياز VARCHAR (40) NOT NULL ، PRIMARY KEY (معرف المستخدم) ) ؛

وصف القائمة 3:

شيء واحد يجب أن تعرفه أنه إذا لم يكن لديك تسهيلات MySQL لاستخدام هذا الاستعلام ، لذلك يجب عليك اتباع مقالتي السابقة حول. من هذا الرابط ، ستتمكن من فهم التثبيت والمتطلبات. وكيف يمكننا استخدامه.

في استعلام القائمة 3 استخدمنا كل تلك الأشياء التي نحتاجها لاستمارة التسجيل. نظرًا لوجود متغيرات البريد الإلكتروني والاسم الكامل وكلمة المرور واسم المستخدم. سيقوم هذا المتغير بتخزين بيانات المستخدم ، والتي سيقوم بإدخالها في نموذج التسجيل في الشكل 2 من أجل التسجيل.

بعد كل هذه الأعمال ، سنعمل مع برمجة PHP وهي لغة برمجة من جانب الخادم. لهذا السبب تحتاج إلى إنشاء اتصال بقاعدة البيانات.

القائمة 4: اتصال قاعدة البيانات

وصف القائمة 4:

أنشأنا اتصالًا بين قاعدة البيانات وصفحات الويب الخاصة بنا. ولكن إذا كنت لا تعرف ما إذا كان يعمل أم لا ، فاستخدم شيئًا واحدًا آخر في آخر قائمة تحقق 5 له.

قائمة 5: التحقق من اتصال قاعدة البيانات

قائمة الوصف 5:

في القائمة 5 ، حاولت للتو أن أوضح لك أنه يمكنك التحقق من الاتصال بين قاعدة البيانات و PHP وتأكيده. وهناك شيء آخر لن نستخدم رمز قائمة 5 في صفحة الويب الخاصة بنا. لأنه فقط لجعلك تفهم كيف يمكنك التحقق من اتصال MySQL.

سنقوم الآن بكتابة تطبيق برمجة PHP للتحقق أولاً من توفر المستخدم ثم تخزين المستخدم إذا كان مستخدمًا جديدًا على صفحة الويب.

القائمة 6: connectivity-sign-up.php

وصف connectivity-sign-up.php

في تطبيق PHP هذا ، استخدمت أبسط طريقة لإنشاء تطبيق تسجيل لصفحات الويب. كما ترى أولاً ، قمنا بإنشاء اتصال مثل القائمة 4. ثم استخدمنا وظيفتين ، الوظيفة الأولى هي SignUP () والتي يتم استدعاؤها بواسطة عبارة if من آخر تطبيق ، حيث تؤكد أولاً الضغط على التسجيل زر. إذا تم الضغط عليه ، فسيتم استدعاء وظيفة SingUp وستستخدم هذه الوظيفة استعلامًا عن SELECT لجلب البيانات ومقارنتها مع اسم المستخدم والبريد الإلكتروني الذي يتم إدخاله حاليًا من المستخدم. إذا كان اسم المستخدم والبريد الإلكتروني موجودًا بالفعل في قاعدة البيانات ، فسيظهر آسف لأنك مسجّل بالفعل

إذا كان المستخدم جديدًا مثل اسم المستخدم الحالي ومعرف البريد الإلكتروني غير موجود في قاعدة البيانات ، فإن عبارة If ستستدعي NewUser () حيث ستخزن جميع معلومات المستخدم الجديد. وسيصبح المستخدم جزءًا من صفحة الويب.



الشكل 3

في الشكل 3 ، يقوم المستخدم بإدخال البيانات للتسجيل إذا كان المستخدم مستخدمًا قديمًا لصفحة الويب هذه وفقًا لسجلات قاعدة البيانات. لذلك ستعرض صفحة الويب رسالة تفيد بأن المستخدم مسجل بالفعل إذا كان المستخدم جديدًا ، لذا ستعرض صفحة الويب رسالة تفيد بإكمال تسجيل المستخدم.



الشكل 4:

عندما أدخلنا البيانات في نموذج التسجيل (الشكل 4) ، وفقًا لقاعدة البيانات التي أدخلناها في اسم المستخدم والبريد الإلكتروني في نموذج التسجيل للاشتراك ، فهو موجود بالفعل في قاعدة البيانات. لذلك يجب أن نجرب اسم مستخدم جديد وعنوان بريد إلكتروني للتسجيل باستخدام معرف وكلمة مرور جديدين.



الشكل 5

في الشكل 5 ، يؤكد لنا أن اسم المستخدم ومعرف البريد الإلكتروني الذي أدخله. كلاهما غير موجود في سجلات قاعدة البيانات. لذلك تم الآن إنشاء معرف وكلمة مرور جديدين ويمكن للمستخدم استخدام معرفه الجديد وكلمة المرور لتسجيل الدخول في المرة القادمة.

استنتاج:

تعلمنا في هذه المقالة أبسط طريقة لإنشاء صفحة ويب تسجيل. تعلمنا أيضًا كيف تتعامل مع قاعدة البيانات إذا استخدمنا PHP و MySQL. حاولت تزويدك بمعرفة أساسية حول وظائف صفحة الويب الخاصة بالتسجيل. كيف يعمل في النهاية الخلفية ، وكيف يمكننا تغيير مظهره في الواجهة الأمامية. لأي استفسار لا تتردد وتعلق.

مرحبا لجميع القراء!

اليوم سننظر في موضوع مهم إلى حد ما طرحه العديد من أصحاب العمل ، وهو التعددية اللغوية.

ماذا قصدت عندما أتحدث عن تعدد اللغات. حسنًا ، من المؤكد أن كل من قرائي المحترمين قد شاهدوا بوابات رائعة أكثر من مرة ووجدوا أيقونتين صغيرتين بين مجموعة كاملة من المعلومات ، بشكل أساسي مع الأعلام المشهورة ذات الخطوط النجمية والأعلام المحلية ذات اللون الأبيض والأزرق والأحمر. بالطبع ، بعد النقر على إحداها ، تحول خطابنا الروسي المألوف إلى لغة برجوازية () ، أو العكس. لكن هل سألت نفسك يومًا كيف يتم ذلك. حسنًا ، هذا ما سأتحدث عنه.

يجب أن أقول على الفور أنه للعمل مع المواد التي سيتم تقديمها هنا ، ستحتاج إلى دعم PHP على الأقل 4.39.

لذلك ، كما تعلم ، ينقسم محتوى موقعنا إلى ديناميكي وثابت. سوف نشير إلى المحتوى الثابت الذي لن يغير معناه في سياق العمل (الكلمات الرئيسية ، ونص الأخطاء ، وغير ذلك من الهراء). من هنا نبدأ لكن دعنا نحلل كيف سنغير بالضبط لغة قيمة نصية معينة. آمل ألا يقترح أحد استخدام الاستثناءات ، لأنه غير منطقي لدرجة أنه لا يمكن أن يكون أكثر لاعقلانية. بدلاً من ذلك ، أقترح استخدام الثوابت (اقرأ عن نوع البيانات على php.net). سنعلن ببساطة عن كلمة وظيفية ، والتي ، بناءً على معنى اللغة ، ستغير معناها وفقًا لذلك. كيف لنا أن نفعل ذلك؟ نعم ، مثل أي شخص آخر ، سننشئ ملفين مختلفين (على سبيل المثال) ، سيكون لأسمائهما النمط التالي:

Language_map.php؛

كما فهمت بالفعل ، فبدلاً من كلمة "اللغة" ، سنستبدل القيمة التي تميزها لغة معينة... في حالتنا ، سنستخدم رمز لغة مكونًا من حرفين (ru، en، ua، pl، إلخ.).

حسنًا ، لقد اكتشفنا النظرية ، والآن دعنا نطبق معرفتنا في الممارسة. نقوم بإنشاء ملفين. لقد أنشأت ملفات بالترجمة الإنجليزية والروسية ، لكن كيفية إنشائها تناسب ذوقك بالفعل.

ملف: en_map.php

ملف: ru_map.php

لذلك ، في رأيي ، لا يوجد شيء معقد ، وكل شيء مكتوب يخضع لقوانين PHP الأكثر شيوعًا. أولا نتحقق مما إذا كان قد تم التصريح عن الثوابت بالفعل ، إذا كانت كذلك ، فنحن لا نعلن ، وإلا فإننا نعلن.

كان هذا هو الجزء السهل ، والآن دعنا ننتقل إلى موضوع أكثر تعقيدًا - ترجمة الجزء الديناميكي.

لنفترض أن لديك نظام بوابة كبير أو موقعًا بسيطًا ، لكنك ، كمبرمج موهوب يعرف جميع جوانب PHP ، لا تملكه ، لكنك قمت بطلبه. المالك مصمم كامل () ليس إشاعة أو روحًا عن تعقيدات بعض المبرمجين ، لكن لديه رغبة واحدة فقط في أن يعمل كل شيء ، ويمكنه تغيير كل شيء. أما بالنسبة لكل شيء ، فهذه قصة أخرى ، لكننا ما زلنا نسمح له بتغيير معايير لغة الموقع (ولكن ما هو موجود ، بغض النظر عن ما يستمتع به الطفل).

لكن مرة أخرى ، بالعودة إلى معضلة "المصممين والمبرمجين" ، من الضروري أن نذكر مرة أخرى أن مثل هذا الموقع يجب أن يكون بالكامل ، إذا جاز التعبير ، "ما تراه هو ما تحصل عليه" ، وإلا فإنه مستحيل. لذلك ، سأحاول أن أفعل كل شيء حتى لا يسبب تشنجًا عصبيًا بين المبرمجين ، ويمكن أن يرضي المصممين (بمعنى قابلية الاستخدام).

لذا ، فلتسقط بكلمات جوفاء ونتقدم إلى برلين. سنبدأ بالنظرية. لذا ، كيف سنميز اللغات عن المحتوى الديناميكي ، الذي ، في أحسن الأحوال ، يتم إزالته أو تغييره أو حتى إخفاء شيء جيد. الثوابت لا تكفي هنا ، ماذا تفعل؟

أستطيع بالفعل سماع الأفكار التي تدور حولك.

شخصياً ، عندما حاولت إضفاء الحيوية على هذا ، في البداية فعلت ذلك بأكثر الطرق غير المنطقية ، أي ترجمة المقالات ، وقسمت الحقول في الجدول التي كان من المقرر ترجمتها إلى قسمين (أي ، قمت بإنشاء حرف eng الحقل والحقل ru) بهذه الطريقة ، وتحولت الجداول الكبيرة جدًا إلى ضخمة بشكل فاحش. لذلك بدأت في البحث عن بديل ، وصدقوني ، وجدته. أنت بالفعل تشعر بالدفء ، نعم ، قريبًا سنصل إلى الأكثر سخونة. لقد وجدت طريقة للخروج من هذا الموقف ، وأعتزم الآن أن أشرح لك الأمر على أصابعي ، وسيعتمد عليك ما إذا كنت تفهمه أم لا. أولاً ، دعنا نتفق على كل التفاصيل.

بادئ ذي بدء ، نحتاج إلى جدول توضع فيه بيانات الترجمة. لنفترض أن لدينا جدولاً "مقالات" يتم وضع بعض المقالات فيه ، ويجب أن تحتوي ، على سبيل المثال ، على ترجمتين ، ولكن يلزم وجود ترجمة واحدة. سنهتم بمفتاحين فقط ، في حالتنا ، الحقول: الاسم والوصف. سنقوم ببناء النص بهذه الطريقة:

<%eng%>النسخة الإنجليزية من المقال <%ru%>النسخة الروسية من المقال

بعد ذلك ، تكون السلسلة عبارة عن مزيج من هاتين البنيتين وستتم إضافتهما إلى حقلي "العنوان" و "الوصف" لجدول "المقالات".

ستتألف هذه الطريقة من العثور على أول ظهور للكلمة الرئيسية الافتتاحية (على سبيل المثال<%eng%>) ، ثم سنجد أول ظهور للكلمة الرئيسية الختامية. لكن يجب ألا ننسى أننا لا نحتاج إلى المدخل بالضبط ، بل طول الهيكل. في الحالة الأولى ، سنضيف طول الهيكل إلى التواجد الأول للهيكل الافتتاحي ، وستكون الخطوة الثانية هي إيجاد طول هيكل الإغلاق. لكنك تسأل:<Как же мы получим текст?>.

استخدام دالة substr (). المعلمة الأولى هي النص نفسه ، والثانية هي طول الهيكل الافتتاحي ، والثالثة (الأكثر إثارة للاهتمام) هي الفرق بين التواجد الأول لهيكل الإغلاق والنص الطويل. نعم ، أفهم أن الأمر ليس بهذه السهولة ، لكن يجب فهمه. لذلك ، سنفعل هذا الآن في الممارسة العملية. لقد أنشأت وظيفة من شأنها أن تبرز النص بين العلامات الرئيسية... سوف يستغرق الأمر ثلاث معاملات: نص للتحليل ، ولغة للتحليل ، ومجموعة من البنى.

","<%/","%>")) ($ start_tag = strpos ($ data، $ delimiters. $ lang. $ delimiters) + strlen ($ delimiters. $ lang. $ delimiters)؛ $ count = (strpos ($ data، $ delimiters. $ lang. $. المحددات) -strlen ($ data)) $ data = substr ($ data، $ start_tag، $ count)؛ if (trim ($ data) == "") ($ data = NOT_ENTERED؛) إرجاع $ data؛)؟>

كما ترى ، إنها طويلة جدًا ويمكن أن تشعر بالارتباك ، ولكن إذا لم تفهم هذا ، فهذه ليست مشكلة كبيرة ، لأن هناك بالفعل وظيفة للتعداد ، وبعد ذلك بقليل سأفكر في طريقة أخرى لـ نفس الغرض. نعم ، ولا تنسَ إعلان ثابت اللغة NOT_ENTERED في مكان ما ، والذي سيتم تخصيصه لنتيجة عمل الوظيفة إذا كان طول النص يساوي صفرًا.

لذلك ، اكتشفناها بقوة غاشمة ، لكنها الآن تظهر أمامنا مهمة جديدة، تجميع نص عادي في سلسلة منسقة خاصة. هذا بالفعل أسهل بكثير ، وإذا كنت تعرف PHP جيدًا ، فيمكنك بسهولة كتابة هذه الوظيفة ، وإذا كنت لا تزال تسبح ، فالرجاء الذهاب إلى المكتب.

الخوارزمية ليست معقدة وتتألف من استبدال جميع تركيبات اللغة في سطر واحد. في البداية ، في نوبة من الكسل ، أردت قصر النص على عدد معين من اللغات (من الأسهل تنفيذه بهذه الطريقة) ، لكن بعد ذلك غيرت رأيي وحصلت على هذا:

","<%/","%>")) (if (! is_array ($ data)) (die (PARAM_CHECK_ERROR)؛) $ data =" "؛ $ temp =" "؛ $ count = 0؛ foreach ($ data as $ k => $ v) ( if (! is_string ($ k)) (break؛) $ count ++؛ if ($ count> 1 & $ temp = $ k) (die (ERROR_CONSTRUCTION_COUNT)؛) $ temp = $ k؛ $ data. = $ محددات . $ k. $ delimiters. $ v. $ delimiters. $ k. $ delimiters؛) إرجاع $ data؛)؟>

حسنًا ، سأشرح قليلاً هنا. تأخذ الدالة مصفوفة كمعامل. يجب أن تكون بنية المصفوفة كما يلي:

"معرف اللغة" => "نص" ؛

بعد ذلك نتحقق مما إذا كانت المعلمة المستلمة ليست مصفوفة<пока Вася!>.

إذا كانت لا تزال مصفوفة ، فإننا بالطبع نكررها ، ونضع المفتاح في مكان اللغة في البناء من هذا العنصرالمصفوفة الترابطية ، وبدلاً من النص ، بالطبع ، النص نفسه ، أي قيمة المتغير $ v. ثم نقوم بدمج جميع البيانات في سطر واحد. لكنني نسيت أن أذكر أحد التفاصيل المهمة ، بمعنى آخر ، جزء كبير من النص. أولاً ، قبل الحلقة ، أعلنا عن ثلاثة متغيرات: data ، temp ، count ؛

العدد المتغير هو عدد تكرارات الحلقة ، ومع كل جولة تالية من الحلقة ، يزداد العداد. متغير البيانات هو السلسلة الناتجة المستقبلية التي سيتم دمج جميع تراكيب اللغة فيها. لكن المتغيرات العد ودرجة الحرارة أكثر إثارة للاهتمام. ما الذي يحتاجون إليه؟ حسنًا ، على الأرجح ، خمن معظمهم بالفعل من خلال قراءة المصدر ، ولكن بالنسبة لأولئك الذين لم يفعلوا ذلك بعد<дошло>أنا سأشرح. يتم ذلك للتأكد من أن بناء اللغة لم يتكرر أكثر من مرة. لهذا أعلنا عن متغير العد. نظرًا لأن قيمتها الافتراضية هي صفر ، فإننا نتحقق من تنفيذ الحلقة مرة واحدة على الأقل ، لأننا إذا لم نفعل ذلك ، فسيظهر شيء مثل 2 = 2 أو 0 = 0 ، لأن قيمة $ k لم تتغير بعد .... نظرًا لأنه سيتم تجاهل الشيك في المرة الأولى ، فإننا نخصص القيمة لمتغير $ temp بعد التحقق. يتم ذلك أيضًا لسبب ما. في التكرار الأول ، كل شيء سوف يسير على ما يرام ، ولكن إذا كنا لا نزال نخصص قيمة قبل التحقق ، فسيقوم الشيك بالفحص الذي سبق ذكره (2 = 2 ، 3 = 3 ، إلخ). هذا هو السبب في أننا نفعل ذلك بهذه الطريقة.

الآن ، وكنتيجة منطقية ، سننشئ موقعًا صغيرًا ، حيث سيتم تطبيق كل ما سبق:

","<%/","%>")) ($ data = substr ($ data، (strpos ($ data، $ delimiters. $ lang. $ delimiters) + strlen ($ delimiters. $ lang. $ delimiters))))، (strpos ($ data، $ delimiters) . $ lang. $ delimiters) -strlen ($ data)))؛ if (trim ($ data) == "") ($ data = NOT_ENTERED؛) إرجاع $ data؛) وظيفة compilateLanguageString ($ data، $ delimiters = array ("<%","%>","<%/","%>")) (if (! is_array ($ data)) (die (PARAM_CHECK_ERROR)؛) $ data =" "؛ $ temp =" "؛ $ count = 0؛ foreach ($ data as $ k => $ v) ( if (! is_string ($ k)) (break؛) $ count ++؛ if ($ count> 1 & $ temp = $ k) (die (ERROR_CONSTRUCTION_COUNT)؛) $ temp = $ k؛ $ data. = $ محددات . $ k. $ delimiters. $ v. $ delimiters. $ k. $ delimiters؛) return $ data؛) // لا تنسى<статике>if (! isset ($ _ GET ["lang"])) (setcookie ("lang"، $ _ GET ["lang"]) ؛ header ("Location: index.php؟ module = home") ؛) إذا ( isset ($ _COOKIE ["lang"])) (بما في ذلك $ _COOKIE ["lang"]. "_ Map.php"؛) else (بما في ذلك "ru_map.php" :) if (isset ($ _ POST ["add" ])) ($ description = compilateLanguageString (مصفوفة ($ _ POST ["description_en"]، $ _ POST ["description_ru"]))؛ $ title = compilateLanguageString (array ($ _ POST ["titlte_eng"]، $ _ POST ["title_ru"])) ؛ // صدى عملية الإضافة إلى قاعدة البيانات) " "؛ صدى صوت" "؛ صدى صوت" "؛ $ title = ($ _ SERVER [" REMOTE_ADDR "] ==" 127.0.0.1 ")؟ ADMIN_WELCOM:" مرحبًا ، ضيوف! "؛ صدى $ title ؛ صدى""؛ صدى صوت" "؛ صدى صوت"": صدى صوت" "; [بريد إلكتروني محمي] _connect ("localhost"، "root"، "")؛ mysql_select_db ("somedatabase") ؛ [بريد إلكتروني محمي] _query ("SELECT title، description FROM` articles` LIMIT 0،1"، $ conn_id)؛ إذا (mysql_ num_rows ($ q) == 0) (ARTCILES_NOT_FOUNDED؛) آخر ( [بريد إلكتروني محمي] _fetch_array ($ q) ؛ $ title = subTextByLang ($ row ["title"]، $ lang)؛ وصف $ = subTextByLang ($ row ["description"]، $ lang)؛ صدى صوت "

": صدى صوت" "؛ صدى صوت" "؛ صدى صوت" "؛ صدى صوت"
".ARTICLE_TITLE_TEXT."". $ title."
". ARTICLE_DESCRIPTION_TEXT."
". وصف $."
"؛)mysql_close ($ conn_id)؛ // إنه ليس سيئًا للغاية ، الآن نحتاج إلى إنشاء نموذج لإضافة صدى مقال"
"؛ صدى صوت" "؛ صدى صوت" "؛ صدى صوت" "؛ صدى صوت" "؛ صدى صوت" "؛ صدى صوت" "؛ صدى صوت" "؛ صدى صوت" "؛ صدى صوت"
".ARTICLE_TITLE_TEXT." (بالإنكليزية):
".ARTICLE_TITLE_TEXT." (RU):
". ARTICLE_DESCRIPTION_TEXT." (بالإنكليزية):
"؛ صدى صوت" "؛ صدى صوت"
". ARTICLE_DESCRIPTION_TEXT." (RU):
"؛ صدى صوت" "؛ صدى صوت"
"؛ صدى صوت"
"; ?>

حسنا هذا كل شيء. ومع ذلك ، هناك واحدة "لكن" في النص ، لا يمكن للمؤلف إضافة أكثر من خياري ترجمة من خلال النموذج. لن أفعل ، مثل بقية المؤلفين ، أنني قمت بهذا من أجل تدريبك ، لأكون صادقًا ، عندما وصلت إلى هذا المكان ، لم يكن رأسي تقريبًا يطبخ ، لذا أترك الأمر على أكتافك. صدقني ، هناك الكثير من الحلول ، وآمل حقًا أن تجدها. فيما يتعلق بالوظائف ، لا يمكنني القول بنسبة 100٪ أنها لن تتسبب في فشل ، ولكن لا ينبغي أن تكون هناك أخطاء فادحة ، على الرغم من أن أي شيء يمكن أن يحدث. لكنني متأكد بنسبة تزيد عن 60٪ أن بناء الجملة معطل ، لأنني لم أختبر الأمثلة. وهنا من أجلك حقًا تمرين جيدبعد كل شيء ، اصطياد "البراغيث" نشاط مفيد للغاية!

حسنًا ، أعتقد أن هذا المقال يمكن أن ينتهي. إذا فشلت ، لا تدفع الشر على جهاز الكمبيوتر الفقير لديك ، وعلى لوحة المفاتيح ، وحتى على مطوري لغة رائعة مثل PHP ، فلا تتردد في معالجة جميع إخفاقاتك في اتجاهي. لا أعتقد أن هذا سيجعلني أسوأ ، لكن سيكون لديك من يدفع غضبك تجاهه.

لقد بدأت "بداية جيدة ، لكن عبارة التبديل في userLanguage () لا تشعر بأنها صحيحة من منظور موجه للكائن:

يجب أن تمثل الفئة التي تسمى اللغة لغة واحدة تكون عامة بما يكفي لتناسب جميع الحالات: ولكن في الوقت الحالي ، ومهما كانت اللغة التي تمثلها ، فإنها تحتوي على تعريفات لكل منهم تم دمجهم في تلك الطريقة الواحدة.

هل هي قابلة للصيانة؟لا حقا لا. في الوقت الحالي لديك لغتان ، أفترض أنك تعرفهما. ومع ذلك ، إذا كنت ترغب في أي وقت في ترجمته إلى لغة أخرى (ربما باستخدام مجموعة أحرف أخرى ، فستواجه مشكلات تتعلق بالمساحة في الملف ، وحفظ الملف بشكل صحيح ، ودمج الترجمات التي يوفرها أشخاص آخرون لموقعك.

فيما يتعلق بما إذا كنت تريد استخدام قواعد البيانات ، أو الفئات المجردة وما إلى ذلك: قد ترغب في ذلك ، على الرغم من وجود حلول أخرى.

الحل 1: ملف تكوين بسيط

تعد parse_ini_file () أداة صغيرة قوية جدًا تقوم بما تتوقعه بالضبط. باستخدام ملف بسيط مثل هذا الذي سنسميه en.ini:

PAGE_TITLE = عنوان صفحة موقع الويب الخاص بي HEADER_TITLE = عنوان موقع الويب الخاص بي SITE_NAME = موقع الويب الخاص بي SLOGAN = شعاري هنا HEADING = العنوان MENU_LOGIN = تسجيل الدخول MENU_SIGNUP = تسجيل MENU_FIND_RIDE = البحث عن رحلة MENU_ADD_RIDE = إضافة رحلة MENU_LOGOUT = تسجيل الخروج

يمكنك ببساطة استخدام: parse_ini_file ("en.ini") لإرجاع مصفوفة تمامًا كما في بيان التبديل الخاص بك ، مما يسهل على الآخرين (غير المبرمجين) قراءتها وكتابتها نيابةً عنك. وإذا كنت ستستمر بعد ذلك في تسمية الملفات بهذا النمط ، فيمكنك تقليل userLanguage () إلى شيء مثل:

الوظيفة العامة userLanguage () ($ file = "/ path / to / language / config /". $ This-> UserLng. ".Ini" ؛ إذا كان (! File_exists ($ file)) (// خطأ معالجة) إرجاع parse_ini_file ( ملف $) ؛)

الحل 2: فئة الملخص

نظرًا لأن المصفوفة الخاصة بك تعمل بشكل أساسي كطرق جامعية ، يجب أن تحتوي فئة اللغة المجردة على جميع مكونات اللغة التي تحتاجها ، مثل:

لغة الواجهة (الوظيفة العامة getPageTitle () ؛ الوظيفة العامة getHeaderTitle () ؛ الوظيفة العامة getSiteName () ؛ الوظيفة العامة getSlogan () ؛ الوظيفة العامة getHeading () ؛ الوظيفة العامة getMenuLogin () ؛ الوظيفة العامة getMenuSignup () ؛ الوظيفة العامة getMenuFindRide () ؛ الوظيفة العامة getMenuAddRide () ؛ الوظيفة العامة getMenuLogout () ؛)

على الرغم من أن الواجهة صغيرة ، إلا أن تنفيذها قد ينتج عنه ملف كبير ، على الرغم من أنه سيكون أوضح من نمط المصفوفة:

تطبق Class English Language (الوظيفة العامة getHeaderTitle () (تُرجع "عنوان موقع الويب الخاص بي" ؛) الوظيفة العامة getHeading () (إرجاع "العنوان" ؛) // إلخ ...)

لبديل

بدلاً من ذلك ، يمكنك الجمع بين هذه الأنماط والحصول على لغة مفردة مع طرق الحصول على هذه المصفوفة ، على سبيل المثال:

لغة الفصل ($ languageArray ؛ private $ userLanguage ؛ الوظيفة العامة __construct ($ language) ($ this-> userLanguage = $ language ؛ $ this-> languageArray = self :: userLanguage () ؛) الوظيفة الثابتة الخاصة userLanguage () ($ file = "/ path / to / language / config /". $ this-> userLanguage. ".ini" ؛ إذا (! file_exists ($ file)) (// معالجة الخطأ) أعادت parse_ini_file ($ file) ؛) الوظيفة العامة getPageTitle () (إرجاع $ this-> languageArray ["PAGE_TITLE"] ؛) الوظيفة العامة getHeaderTitle () (إرجاع $ this-> languageArray ["HEADER_TITLE"] ؛) // إلخ ...)

والتي ستوفر فوائد كليهما. شخصيًا ، ما لم تكن تخطط لإضافة المزيد من اللغات في المستقبل القريب جدًا ، أعتقد أن الحل رقم 2 سوف يناسبك بشكل أفضل.