Domanda

(Aggiornato un po ' di)

Non sono molto esperto e con l'internazionalizzazione utilizzando PHP, va detto, e un accordo di ricerca in realtà non fornire le risposte che stavo cercando.

Ho bisogno di un modo affidabile per convertire solo 'rilevanti' di testo Unicode per inviare un messaggio SMS, utilizzando PHP (solo temporaneamente, mentre il servizio viene riscritto utilizzando C#) - ovviamente, i messaggi inviati al momento sono inviati come testo normale.

Mi potrebbero convertire il tutto il set di caratteri Unicode (anziché utilizzare lo standard GSM charset), ma che vorrebbe dire che tutti i messaggi sarebbero limitati a 70 caratteri (invece di 160).

Quindi, credo che la mia vera domanda è: che cosa è il modo più affidabile per rilevare l'esigenza di un messaggio per essere codificati in Unicode, quindi ho solo da fare quando è assolutamente necessario (ad es.per i non-latino-lingua caratteri)?

Aggiunte Informazioni:

Va bene, così ho passato la mattina a lavorare su questo, e sono ancora senza ulteriormente rispetto a quando ho iniziato (sicuramente a causa della mia totale mancanza di competenza quando si tratta di set di caratteri di conversione).Ecco quindi la revisione scenario:

Ho SMS messaggi di testo provenienti da una fonte esterna, questa fonte esterna fornisce le risposte a me in testo normale + Unicode slash-caratteri di escape.E. g.il "visualizzato" testo:

Proviamo öäü éàè אין תמיכה בעברית

Restituisce:

Proviamo \u00f6\u00e4\u00fc \u00e9\u00e0\u00e8 \u05d0\u05d9\u05df \u05ea\u05de\u05d9\u05db\u05d4 \u05d1\u05e2\u05d1\u05e8\u05d9\u05ea

Ora, posso inviare il mio provider SMS in chiaro, GSM 03.38 o Unicode.Ovviamente, l'invio di quanto sopra, come chiaro si traduce in un sacco di caratteri mancanti (sono sostituiti da spazi dal mio provider) - ho bisogno di adottare relative a quanto contenuto c'è.Quello che voglio fare con questo è la seguente:

  1. Se tutto il testo è all'interno del GSM 03.38 codepage, inviarlo come-è.(Tutti i caratteri ebraici di cui sopra, rientrano in questa categoria, ma devono essere convertiti.)

  2. In caso contrario, la conversione in Unicode, e di inviare più messaggi multipli (come Unicode limite è di 70 caratteri non di 160 per un SMS).

Come ho detto sopra, sono perplesso su come farlo in PHP (C# non era molto più di un problema a causa di alcune semplici funzioni di conversione built-in), ma è abbastanza probabile che mi manca solo l'ovvio, qui.Non riuscivo a trovare un pre-made classi conversione per la codifica a 7 bit in PHP, sia - e i miei tentativi di convertire la stringa di me e inviarlo sembrava inutile.

Qualsiasi aiuto sarebbe molto apprezzato.

È stato utile?

Soluzione

A che fare con esso concettualmente prima di entrare nei meccanismi, e mi scuso se questo è ovvio, una stringa può essere definito come una sequenza di caratteri Unicode (Unicode essere un database che fornisce un numero di identificazione noto come un punto di codice per ogni personaggio che si potrebbe aver bisogno di lavorare.GSM-338 contiene un sottoinsieme di caratteri Unicode, in modo che quello che stai facendo è l'estrazione di un set di carattere da una stringa, e controllare per vedere se il set è contenuto in 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;
    }
}

Che lascia la definizione della funzione codepoint($stringa), che non è costruito in PHP.PHP capisce una stringa da una sequenza di byte, piuttosto che una sequenza di caratteri Unicode.Il modo migliore per colmare il gap è quello di ottenere il vostro stringhe in UTF8, quanto più rapidamente possibile e tenerli in UTF8 come a lungo possibile, è necessario utilizzare altre codifiche quando ha a che fare con sistemi esterni, ma di isolare la conversione per l'interfaccia di sistema e trattare solo con utf8 internamente.

Le funzioni di cui hai bisogno per la conversione tra php stringhe in utf8 e sequenze di carattere può essere trovato alla http://hsivonen.iki.fi/php-utf8/ , in modo che il tuo carattere() funzione.

Se stai prendendo i dati da una fonte esterna che dà Unicode slash-caratteri di escape ("proviamo \u00f6\u00e4\u00fc..."), la stringa di escape formato devono essere convertiti in utf8.Non so sbrigativo di una funzione per fare questo, se uno non può essere trovato, è una questione di stringa/regex di elaborazione + l'utilizzo del hsivonen.iki.fi funzioni, per esempio quando si colpisce \u00f6, sostituirlo con il utf8 rappresentazione del codepoint 0xf6.

Altri suggerimenti

Anche se questo è un vecchio thread che ho avuto di recente per risolvere un problema simile e volevo postare la mia risposta.Il codice PHP è un po ' semplice.Si inizia con un faticosamente vasta gamma di GSM valido codici di caratteri in un array, poi controlla semplicemente se il carattere corrente è in un array ord($stringa) funzione che restituisce il valore ascii del primo carattere della stringa passata.Ecco il codice che uso per verificare se una stringa è GSM vale la pena.

    $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;
}

So che questo non è il codice php, ma penso che potrebbe aiutare comunque.Questo è come fare un app che ho scritto per rilevare se è possibile inviare come GSM 03.38 (si potrebbe fare qualcosa di simile per il testo normale).Dispone di due tabelle di conversione, uno per il normale GSM e uno per esteso.E poi una funzione che consente di scorrere tutti i caratteri di controllo se può essere convertito.

#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 avrà un migliore supporto unicode, ma ci sono un paio di funzioni che si possono utilizzare.

Il mio primo pensiero è stato mb_convert_encoding ma come ti dicevo per ridurre i messaggi di 70 caratteri, quindi forse è possibile utilizzare questo in combinazione con mb_detect_encoding?

Vedere: Multibyte Funzioni

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)

o

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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top