الطريقة الأكثر فعالية للقيام بملف اللغة في PHP؟

StackOverflow https://stackoverflow.com/questions/1414079

  •  06-07-2019
  •  | 
  •  

سؤال

تم تحديث الأسئلة بدلاً من طرح سؤال جديد...

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

1)
ماذا يعني i18n، الذي أراه كثيرًا عند البحث عن ترجمة اللغة على SO؟

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

يبدو الأمر وكأنه ألم، وأنا أفهم أنه من المفترض أن يكون هذا هو أفضل طريق يمكن اتباعه، حسنًا، يبدو أن الجميع يقولون ذلك.
فهل يمكن لأحد أن يقول لي لماذا هذا هو الطريق الذي يجب أن نسلكه؟

3)
يعجبني حقًا بساطة هذا النهج ، فقط بناء صفيف لغة واستدعاء العبارة التي تحتاجها في وظيفة مثل المثال أدناه ، يمكنك بعد ذلك تضمين ملف مع صفيف اللغة المناسب.

ما أريد معرفته حقًا هو، هل ستكون هذه طريقة أداء أقل جودة على موقع كبير وحركة مرور عالية مقارنة باستخدام gettext، وإذا كان الأمر كذلك، هل يمكنك توضيح السبب من فضلك؟

<?PHP
//Have seperate language files for each language I add, this would be english file
function lang($phrase){
    static $lang = array(
        'NO_PHOTO' => 'No photo\'s available',
        'NEW_MEMBER' => 'This user is new'
    );
    return $lang[$phrase];
}
//Then in application where there is text from the site and not from users I would do something like this
echo lang('NO_PHOTO');  // No photo's available would show here
?>

* بعض التعليمات البرمجية المستخدمة من إجابة brianreavis أدناه

هل كانت مفيدة؟

المحلول

لا تعيد اختراع العجلة.استخدم على سبيل المثال الحصول على النص أو Zend_Translate.

نصائح أخرى

ربما يكون من الأفضل تحديد وظيفة تتعامل مع تعيين اللغة لديك.بهذه الطريقة، إذا كنت يفعل إذا كنت ترغب في تغيير طريقة عمله لاحقًا، فلن تضطر إلى البحث في مئات البرامج النصية بحثًا عن الحالات التي استخدمتها $lang[...] واستبدالها بشيء آخر.

شيء من هذا القبيل سيعمل وسيكون لطيفًا وسريعًا:

function lang($phrase){
    static $lang = array(
        'NO_PHOTO' => 'No photo\'s available',
        'NEW_MEMBER' => 'This user is new'
    );
    return $lang[$phrase];
}

يصنع بالتأكيد تم الإعلان عن المصفوفة static داخل الوظيفة حتى لا تتم إعادة تخصيصها في كل مرة يتم فيها استدعاء الوظيفة.هذا مهم بشكل خاص عندما $lang كبيرة حقا.

لتستخدمها:

echo lang('NO_PHOTO');

للتعامل مع لغات متعددة، ما عليك سوى تحديد هذه الوظيفة في ملفات متعددة (مثل en.php, fr.php, الخ) و require() المناسب للمستخدم .

قد يعمل هذا بشكل أفضل:

function _L($phrase){
static $_L = array(
    'NO_PHOTO' => 'No photo\'s available',
    'NEW_MEMBER' => 'This user is new'
);

     return (!array_key_exists($phrase,$_L)) ? $phrase : $_L[$phrase];
}

وهذا ما أستخدمه الآن.إذا لم يتم العثور على اللغة، فستعيد العبارة بدلاً من الخطأ.

يجب ملاحظة أن المصفوفة لا يمكن أن تحتوي على أكثر من 65500 عنصر تقريبًا.ينبغي أن يكون كافيا ولكن جيدا، فقط أقول.

إليك بعض التعليمات البرمجية التي أستخدمها للتحقق من لغة المستخدم:

<?php
function setSessionLanguageToDefault() {
    $ip=$_SERVER['REMOTE_ADDR'];
    $url='http://api.hostip.info/get_html.php?ip='.$ip;
    $data=file_get_contents($url);
    $s=explode (':',$data);
    $s2=explode('(',$s[1]);

    $country=str_replace(')','',substr($s2[1], 0, 3));

    if ($country=='us') {
        $country='en';
    }

    $country=strtolower(ereg_replace("[^A-Za-z0-9]", "", $country ));
    $_SESSION["_LANGUAGE"]=$country;
}

if (!isset($_SESSION["_LANGUAGE"])) {
    setSessionLanguageToDefault();
}

if (file_exists(APP_DIR.'/language/'.$_SESSION["_LANGUAGE"].'.php')) {
    include(APP_DIR.'/language/'.$_SESSION["_LANGUAGE"].'.php');
} else {
    include(APP_DIR.'/language/'.DEFAULT_LANG.'.php');
}

?>

لم يتم ذلك بعد، ولكن أعتقد أن هذا قد يساعد كثيرًا.

لا تكتب إطار اللغة الخاص بك.يستخدم الحصول على النص.PHP لديها معيار الارتباطات التي يمكنك تثبيتها.

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

1) I18N قصير للتدويل ولديه بعض أوجه التشابه مع I-Eigheen-N.

2) في رأيي الصادق ، يعد GetText مضيعة للوقت.

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

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

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

للأسف الحصول على النص لا يعمل بشكل جيد ويواجه مشكلات في مواقف مختلفة كما هو الحال في أنظمة تشغيل مختلفة (Windows أو Linux) ومن الصعب للغاية جعله يعمل.

بالإضافة إلى أنه يتطلب منك تعيين الكثير من متغيرات البيئة والمجالات وهذا ليس له أي معنى.

إذا كان المطور يريد ببساطة الحصول على ترجمة نص، فيجب عليه فقط تعيين مسار الملف .mo والحصول على الترجمة باستخدام وظيفة واحدة مثل ترجمة("hello"،"en_EN")؛مع gettext هذا غير ممكن.

لماذا لا تجعلها مجرد مجموعة متعددة الأبعاد... مثل هذا

<?php

$lang = array(
    'EN'=> array(
        'NO_PHOTO'=>'No photo\'s avaiable',
        'NEW_MEMBER'=>'This user is new',
    ),
    'MY'=> array(
        'NO_PHOTO'=>'Tiada gambar',
        'NEW_MEMBER'=>'Ini adalah pengguna baru',
    )
);

?>

انت تستطيع فعل ذالك:

class T {
const language = "English";
const home = "Home";
const blog = "Blog";
const forum = "Forum";
const contact = "Support";
}

سيكون لديك ملف مثل هذا لكل لغة.لاستخدام النص:

There is no place like <?=T::home?>.

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

ربما يمكن تحسين الوصول، على سبيل المثال:

class T {
    const home = "home";

    public static function _ ($name) {
        $value = @constant("self::$name");
        return $value ? $value : $name;
    }

    // Or maybe through an instance:
    public function __get ($name) {
        $value = @constant("self::$name");
        return $value ? $value : $name;
    }
}
echo "There is no " . T::_("place") . " like " . T::_("home");
$T = new T();
echo "There is no " . $T->place . " like " . $T->home;

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top