Inici de sessió d'usuari


Com converteixo entre de jocs de caràcters amb php d'una manera que sigui portable?


En el nostre idioma, els jocs de caràcters que es fan servir més son utf-8, iso-8859-1 o iso-8859-15 (i n'hi ha més!). Tanmateix, en funció de les eines per a les quals generem la sortida (correu, html, mail...) és possible que volguem fer conversions de texte entre algun d'aquests jocs de caràcters.
Amb php hi ha diverses maneres de fer-ho, cadascuna d'elles requereix que certs mòduls estiguin configurats. Podem trovar diferències de configuració entre servidors, el resultat és que el codi que funciona en un d'ells, podria no funcionar en un altre.

El que es vol és ilustrar un mètode per aconseguir que el codi sigui portable independentment de la configuració.
Una manera és preguntant quina funció tenim disponible, i en quan en trovem una, fer-la servir.

En aquest exemple es converteix $str provant-ho successivament amb les funcions recode_string, iconv i mb_convert_string. Si en trova cap d'aquestes, es farà la conversió:

        if (function_exists('recode_string'))
          $str = recode_string("UTF-8..ISO-8859-1",$str);
        else if (function_exists('iconv'))
          $str = iconv("UTF-8","ISO-8859-1",$str) );
        else if (function_exists('mb_convert_encoding'))
          $str = mb_convert_encoding( $str, "ISO-8859-1", "UTF-8") );

Si la conversió cal fer-la freqüentment, llavors és possible que ens interessi encapsular aquesta funció dins d'una de pròpia que faci la tasca de cercar el mètode adequat en un sol lloc.
Finalment, i ja en el cas de que no disposem de cap sistema de fer conversió, sempre podem fer-nos-la nosaltres. La "pega" és que haurem d'afegir molt més codi i la conversió només estarà disponible en la direcció que haguem codificat, un exemple de la mateixa conversió codificada (utf-8 a iso-8859-1) podria ser aquest:

function utf8toiso8859($string)
{    
 $returns = "";
$UTF8len = array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2,
 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6);
 $pos = 0;
 $antal = strlen($string);
 
 do
 {
   $c = ord($string[$pos]);
   $len = $UTF8len[($c >> 2) & 0x3F];
   switch ($len)
   {
     case 6:
       $u = $c & 0x01;
       break;
     case 5:
       $u = $c & 0x03;
       break;
     case 4:
       $u = $c & 0x07;
       break;
     case 3:
       $u = $c & 0x0F;
       break;
     case 2:
       $u = $c & 0x1F;
       break;
     case 1:
       $u = $c & 0x7F;
       break;
     case 0:  /* comença un nou caràcter inesperadament */
       $u = $c & 0x3F;
       $len = 5;
       break;
   }
   while (--$len && (++$pos < $antal && $c = ord($string[$pos])))
   {
     if (($c & 0xC0) == 0x80)
       $u = ($u << 6) | ($c & 0x3F);
     else
     { /* comença un nou caràcter inesperadament */
       $pos--;
       break;
     }
   }
   if ($u <= 0xFF)
     $returns .= chr($u);
   else
    $returns .= '?';
 } while (++$pos < $antal);
 return $returns;
}