سؤال

(تحديث قليلا)

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

أنا في حاجة إلى العمل بها طريقة يمكن الاعتماد عليها لتحويل فقط 'ذات' من النص إلى Unicode إرسال رسالة SMS باستخدام PHP (مؤقتا فقط ، بينما خدمة إعادة كتابة باستخدام C#) - ومن الواضح أن الرسائل المرسلة في اللحظة التي يتم إرسالها كنص عادي.

لا يمكن تصور تحويل كل شيء إلى محارف يونيكود (بدلا من استخدام معيار GSM محارف) ، ولكن هذا يعني أن كل الرسائل ستكون في حدود 70 حرفا (بدلا من 160).

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

إضافة معلومات:

حسنا, لقد قضيت الصباح في هذا العمل و ما زلت لا مزيد على أكثر عندما بدأت (بالتأكيد بسبب انعدام الكفاءة عندما يتعلق الأمر محارف تحويل).حتى هنا هو تنقيح السيناريو:

لدي النصية SMS الرسائل القادمة من مصدر خارجي ، وهذا مصدر خارجي يوفر الردود لي في نص عادي + Unicode القطع هرب الشخصيات.E. g.على 'عرض' النص:

دعونا اختبار öäü éàè אין תמיכה בעברית

العوائد:

دعونا اختبار \u00f6\u00e4\u00fc \u00e9\u00e0\u00e8 \u05d0\u05d9\u05df \u05ea\u05de\u05d9\u05db\u05d4 \u05d1\u05e2\u05d1\u05e8\u05d9\u05ea

الآن أستطيع أن أرسل إلى موفر SMS في نص عادي, GSM 03.38 أو يونيكود.ومن الواضح إرسال أعلاه عادي النتائج في الكثير من الأحرف الناقصة (إنهم استبدال المساحات من قبل مزود بلدي) - أنا بحاجة إلى اعتماد ذات الصلة إلى المحتوى الذي هناك.ما أريد أن هل مع هذا هي التالية:

  1. إذا كل نص هو في GSM 03.38 الشفرة, إرسال كما هو.(جميع الأحرف العبرية أعلاه تناسب هذه الفئة ، ولكن تحتاج إلى تحويلها.)

  2. وإلا تحويله إلى Unicode وإرسالها عبر رسائل متعددة (كما Unicode حد 70 حرف لا 160 الرسالة القصيرة).

كما قلت أعلاه, أنا الحيرة على القيام بذلك في PHP (C# لم يكن بكثير من قضية بسبب بعض بسيطة تحويل وظائف المدمج في), لكنه من المحتمل جدا أنا في عداد المفقودين هو واضح هنا.لم أجد أي قبل إجراء التحويل الطبقات 7 بت ترميز في PHP, إما ومحاولة تحويل السلسلة نفسي وإرسالها على ما يبدو غير مجدية.

أي مساعدة سيكون موضع تقدير كبير.

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

المحلول

للتعامل مع هذا المفهوم قبل الدخول في آليات و أعتذر إذا كان أي من هذه هو واضح ، سلسلة يمكن تعريفها بأنها سلسلة أحرف Unicode ، Unicode كونه قاعدة البيانات التي تعطي رقم الهوية المعروفة باسم نقطة رمز إلى كل حرف قد تحتاج إلى العمل مع.GSM-338 يحتوي على مجموعة فرعية من أحرف Unicode ، لذلك ما تفعله هو استخراج مجموعة من codepoints من سلسلة الخاص بك و فحص لمعرفة ما إذا كان هذا هو مجموعة الواردة في GSM-338.

// second column of http://unicode.org/Public/MAPPINGS/ETSI/GSM0338.TXT
$gsm338_codepoints = array(0x0040, 0x0000, ..., 0x00fc, 0x00e0)
$can_use_gsm338 = true;
foreach(codepoints($mystring) as $codepoint){
    if(!in_array($codepoint, $gsm338_codepoints)){
      $can_use_gsm338 = false;
      break;
    }
}

أن يترك تعريف الدالة codepoints($string) ، وهي ليست بنيت في PHP.PHP يفهم سلسلة إلى سلسلة من البايتات بدلا من سلسلة أحرف Unicode.أفضل طريقة سد الثغرة هو الحصول على سلاسل الخاص بك إلى UTF8 بسرعة كما يمكنك والاحتفاظ بها في UTF8 طالما يمكنك - سيكون لديك لاستخدام أخرى ترميزات عند التعامل مع الأنظمة الخارجية ، ولكن عزل التحويل إلى واجهة هذا النظام والتعامل فقط مع utf8 داخليا.

الوظائف التي تحتاج إلى تحويل بين php السلاسل في utf8 و تسلسل codepoints يمكن العثور عليها في http://hsivonen.iki.fi/php-utf8/ حتى أن codepoints() وظيفة.

إذا كنت تأخذ البيانات من مصدر خارجي يعطيك Unicode القطع هرب الأحرف ("دعونا اختبار \u00f6\u00e4\u00fc...") ، سلسلة الهروب تنسيق ينبغي تحويلها إلى utf8.أنا لا أعرف مرتجلا من وظيفة للقيام بذلك ، إذا كان أحد لا يمكن العثور على انها مسألة سلسلة/regex تجهيز + استخدام hsivonen.ايكي.فاي الوظائف ، على سبيل المثال عندما ضرب \u00f6 استبدال ذلك مع utf8 تمثيل codepoint 0xf6.

نصائح أخرى

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

    $valid_gsm_keycodes = Array(   
        0x0040, 0x0394, 0x0020, 0x0030, 0x00a1, 0x0050, 0x00bf, 0x0070,
        0x00a3, 0x005f, 0x0021, 0x0031, 0x0041, 0x0051, 0x0061, 0x0071,
        0x0024, 0x03a6, 0x0022, 0x0032, 0x0042, 0x0052, 0x0062, 0x0072,
        0x00a5, 0x0393, 0x0023, 0x0033, 0x0043, 0x0053, 0x0063, 0x0073,
        0x00e8, 0x039b, 0x00a4, 0x0034, 0x0035, 0x0044, 0x0054, 0x0064, 0x0074,
        0x00e9, 0x03a9, 0x0025, 0x0045, 0x0045, 0x0055, 0x0065, 0x0075,
        0x00f9, 0x03a0, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, 0x0076,
        0x00ec, 0x03a8, 0x0027, 0x0037, 0x0047, 0x0057, 0x0067, 0x0077, 
        0x00f2, 0x03a3, 0x0028, 0x0038, 0x0048, 0x0058, 0x0068, 0x0078,
        0x00c7, 0x0398, 0x0029, 0x0039, 0x0049, 0x0059, 0x0069, 0x0079,
        0x000a, 0x039e, 0x002a, 0x003a, 0x004a, 0x005a, 0x006a, 0x007a,
        0x00d8, 0x001b, 0x002b, 0x003b, 0x004b, 0x00c4, 0x006b, 0x00e4,
        0x00f8, 0x00c6, 0x002c, 0x003c, 0x004c, 0x00d6, 0x006c, 0x00f6,
        0x000d, 0x00e6, 0x002d, 0x003d, 0x004d, 0x00d1, 0x006d, 0x00f1,
        0x00c5, 0x00df, 0x002e, 0x003e, 0x004e, 0x00dc, 0x006e, 0x00fc,
        0x00e5, 0x00c9, 0x002f, 0x003f, 0x004f, 0x00a7, 0x006f, 0x00e0 );


        for($i = 0; $i < strlen($string); $i++) {
            if(!in_array($string[$i], $valid_gsm_keycodes)) return false;
        }

        return true;
function is_gsm0338( $utf8_string ) {
    $gsm0338 = array(
        '@','Δ',' ','0','¡','P','¿','p',
        '£','_','!','1','A','Q','a','q',
        '$','Φ','"','2','B','R','b','r',
        '¥','Γ','#','3','C','S','c','s',
        'è','Λ','¤','4','D','T','d','t',
        'é','Ω','%','5','E','U','e','u',
        'ù','Π','&','6','F','V','f','v',
        'ì','Ψ','\'','7','G','W','g','w',
        'ò','Σ','(','8','H','X','h','x',
        'Ç','Θ',')','9','I','Y','i','y',
        "\n",'Ξ','*',':','J','Z','j','z',
        'Ø',"\x1B",'+',';','K','Ä','k','ä',
        'ø','Æ',',','<','L','Ö','l','ö',
        "\r",'æ','-','=','M','Ñ','m','ñ',
        'Å','ß','.','>','N','Ü','n','ü',
        'å','É','/','?','O','§','o','à'
     );
    $len = mb_strlen( $utf8_string, 'UTF-8');

    for( $i=0; $i < $len; $i++)
        if (!in_array(mb_substr($utf8_string,$i,1,'UTF-8'), $gsm0338))
            return false;

    return true;
}

أعرف أن هذا ليس كود php, ولكن أعتقد أنه قد يساعد على أية حال.هذا هو كيف أفعل ذلك في التطبيق كتبت للكشف عن إذا كان من الممكن أن ترسل مثل GSM 03.38 (هل يمكن أن تفعل شيئا من هذا القبيل عن نص عادي).فقد اثنين من جداول الترجمة واحدة العادي GSM واحد الموسعة.ثم وظيفة الحلقات من خلال جميع الشخصيات التحقق من ما إذا كان يمكن تحويلها.

#define UCS2_TO_GSM_LOOKUP_TABLE_SIZE    0x100
#define NON_GSM                              0x80 
#define UCS2_GCL_RANGE                  24
#define UCS2_GREEK_CAPITAL_LETTER_ALPHA 0x0391
#define EXTEND                                0x001B
// note that the ` character is mapped to ' so that all characters that can be typed on
// a standard north american keyboard can be converted to the GSM default character set
static unsigned char  Ucs2ToGsm[UCS2_TO_GSM_LOOKUP_TABLE_SIZE] =
{           /*+0x0      +0x1        +0x2        +0x3        +0x4        +0x5        +0x6        +0x7*/
/*0x00*/    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,
/*0x08*/    NON_GSM,    NON_GSM,    0x0a,       NON_GSM,    NON_GSM,    0x0d,       NON_GSM,    NON_GSM,
/*0x10*/    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,
/*0x18*/    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,
/*0x20*/    0x20,       0x21,       0x22,       0x23,       0x02,       0x25,       0x26,       0x27,
/*0x28*/    0x28,       0x29,       0x2a,       0x2b,       0x2c,       0x2d,       0x2e,       0x2f,
/*0x30*/    0x30,       0x31,       0x32,       0x33,       0x34,       0x35,       0x36,       0x37,
/*0x38*/    0x38,       0x39,       0x3a,       0x3b,       0x3c,       0x3d,       0x3e,       0x3f,
/*0x40*/    0x00,       0x41,       0x42,       0x43,       0x44,       0x45,       0x46,       0x47,
/*0x48*/    0x48,       0x49,       0x4a,       0x4b,       0x4c,       0x4d,       0x4e,       0x4f,
/*0x50*/    0x50,       0x51,       0x52,       0x53,       0x54,       0x55,       0x56,       0x57,
/*0x58*/    0x58,       0x59,       0x5a,       EXTEND,     EXTEND,     EXTEND,     EXTEND,     0x11,
/*0x60*/    0x27,       0x61,       0x62,       0x63,       0x64,       0x65,       0x66,       0x67,
/*0x68*/    0x68,       0x69,       0x6a,       0x6b,       0x6c,       0x6d,       0x6e,       0x6f,
/*0x70*/    0x70,       0x71,       0x72,       0x73,       0x74,       0x75,       0x76,       0x77,
/*0x78*/    0x78,       0x79,       0x7a,       EXTEND,     EXTEND,     EXTEND,     EXTEND,     NON_GSM,
/*0x80*/    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,
/*0x88*/    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,
/*0x90*/    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,
/*0x98*/    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,
/*0xa0*/    NON_GSM,    0x40,       NON_GSM,    0x01,       0x24,       0x03,       NON_GSM,    0x5f,
/*0xa8*/    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,
/*0xb0*/    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,
/*0xb8*/    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    0x60,
/*0xc0*/    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    0x5b,       0x0e,       0x1c,       0x09,
/*0xc8*/    NON_GSM,    0x1f,       NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    0x60,
/*0xd0*/    NON_GSM,    0x5d,       NON_GSM,    NON_GSM,    NON_GSM,    NON_GSM,    0x5c,       NON_GSM,
/*0xd8*/    0x0b,       NON_GSM,    NON_GSM,    NON_GSM,    0x5e,       NON_GSM,    NON_GSM,    0x1e,
/*0xe0*/    0x7f,       NON_GSM,    NON_GSM,    NON_GSM,    0x7b,       0x0f,       0x1d,       NON_GSM,
/*0xe8*/    0x04,       0x05,       NON_GSM,    NON_GSM,    0x07,       NON_GSM,    NON_GSM,    NON_GSM,
/*0xf0*/    NON_GSM,    0x7d,       0x08,       NON_GSM,    NON_GSM,    NON_GSM,    0x7c,       NON_GSM,
/*0xf8*/    0x0c,       0x06,       NON_GSM,    NON_GSM,    0x7e,       NON_GSM,    NON_GSM,    NON_GSM
};

static unsigned char Ucs2GclToGsm[UCS2_GCL_RANGE + 1] =
{
/*0x0391*/  0x41, // Alpha A
/*0x0392*/  0x42, // Beta B
/*0x0393*/  0x13, // Gamma
/*0x0394*/  0x10, // Delta
/*0x0395*/  0x45, // Epsilon E
/*0x0396*/  0x5A, // Zeta Z
/*0x0397*/  0x48, // Eta H
/*0x0398*/  0x19, // Theta
/*0x0399*/  0x49, // Iota I
/*0x039a*/  0x4B, // Kappa K
/*0x039b*/  0x14, // Lambda
/*0x039c*/  0x4D, // Mu M
/*0x039d*/  0x4E, // Nu N
/*0x039e*/  0x1A, // Xi
/*0x039f*/  0x4F, // Omicron O
/*0x03a0*/  0X16, // Pi
/*0x03a1*/  0x50, // Rho P
/*0x03a2*/  NON_GSM,
/*0x03a3*/  0x18, // Sigma
/*0x03a4*/  0x54, // Tau T
/*0x03a5*/  0x59, // Upsilon Y
/*0x03a6*/  0x12, // Phi 
/*0x03a7*/  0x58, // Chi X
/*0x03a8*/  0x17, // Psi
/*0x03a9*/  0x15  // Omega
};

bool Gsm0338Encoding::IsNotGSM( wchar_t szUnicodeChar )
{
    bool    result = true;
    if( szUnicodeChar < UCS2_TO_GSM_LOOKUP_TABLE_SIZE )
    {
        result = ( Ucs2ToGsm[szUnicodeChar] == NON_GSM );
    }
    else if( (szUnicodeChar >= UCS2_GREEK_CAPITAL_LETTER_ALPHA) &&
                (szUnicodeChar <= (UCS2_GREEK_CAPITAL_LETTER_ALPHA + UCS2_GCL_RANGE)) )
    {
        result = ( Ucs2GclToGsm[szUnicodeChar - UCS2_GREEK_CAPITAL_LETTER_ALPHA] == NON_GSM );
    }
    else if( szUnicodeChar == 0x20AC ) // €
    {
        result = false;
    }
    return result;
}

bool Gsm0338Encoding::IsGSM( const std::wstring& str )
{
    bool    result = true;
    if( std::find_if( str.begin(), str.end(), IsNotGSM ) != str.end() )
    {
        result = false;
    }
    return result;
}

PHP6 سوف يكون أفضل دعم يونيكود ولكن هناك عدد قليل من الوظائف يمكنك استخدام.

كانت فكرتي الأولى mb_convert_encoding ولكن كما قلت هذا تقصير رسائل إلى 70 حرف - لذا ربما يمكنك استخدام هذا بالتزامن مع mb_detect_encoding?

انظر: Multibyte وظائف

preg_match('/^[\x0A\x0C\x0D\x20-\x5F\x61-\x7E\xA0\xA1\xA3-\xA5\xA7'.
    '\xBF\xC4-\xC6\xC9\xD1\xD6\xD8\xDC\xDF\xE0\xE4-\xE9\xEC\xF1'.
    '\xF2\xF6\xF8\xF9\xFC'.
    json_decode('"\u0393\u0394\u0398\u039B\u039E\u03A0\u03A3\u03A6\u03A8\u03A9\u20AC"').
    ']*$/u', $text)

أو

preg_match('/^[\x0A\x0C\x0D\x20-\x5F\x61-\x7E\xA0\xA1\xA3-\xA5\xA7\xBF\xC4-\xC6\xC9\xD1\xD6\xD8\xDC\xDF\xE0\xE4-\xE9\xEC\xF1\xF2\xF6\xF8\xF9\xFCΓΔΘΛΞΠΣΦΨΩ€]*$/u', $text)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top