<?php
// for those who has PHP older than version 5.3
class IDN {
// adapt bias for punycode algorithm
private static function punyAdapt(
$delta,
$numpoints,
$firsttime
) {
$delta = $firsttime ? $delta / 700 : $delta / 2;
$delta += $delta / $numpoints;
for ($k = 0; $delta > 455; $k += 36)
$delta = intval($delta / 35);
return $k + (36 * $delta) / ($delta + 38);
}
// translate character to punycode number
private static function decodeDigit($cp) {
$cp = strtolower($cp);
if ($cp >= 'a' && $cp <= 'z')
return ord($cp) - ord('a');
elseif ($cp >= '0' && $cp <= '9')
return ord($cp) - ord('0')+26;
}
// make utf8 string from unicode codepoint number
private static function utf8($cp) {
if ($cp < 128) return chr($cp);
if ($cp < 2048)
return chr(192+($cp >> 6)).chr(128+($cp & 63));
if ($cp < 65536) return
chr(224+($cp >> 12)).
chr(128+(($cp >> 6) & 63)).
chr(128+($cp & 63));
if ($cp < 2097152) return
chr(240+($cp >> 18)).
chr(128+(($cp >> 12) & 63)).
chr(128+(($cp >> 6) & 63)).
chr(128+($cp & 63));
// it should never get here
}
// main decoding function
private static function decodePart($input) {
if (substr($input,0,4) != "xn--") // prefix check...
return $input;
$input = substr($input,4); // discard prefix
$a = explode("-",$input);
if (count($a) > 1) {
$input = str_split(array_pop($a));
$output = str_split(implode("-",$a));
} else {
$output = array();
$input = str_split($input);
}
$n = 128; $i = 0; $bias = 72; // init punycode vars
while (!empty($input)) {
$oldi = $i;
$w = 1;
for ($k = 36;;$k += 36) {
$digit = IDN::decodeDigit(array_shift($input));
$i += $digit * $w;
if ($k <= $bias) $t = 1;
elseif ($k >= $bias + 26) $t = 26;
else $t = $k - $bias;
if ($digit < $t) break;
$w *= intval(36 - $t);
}
$bias = IDN::punyAdapt(
$i-$oldi,
count($output)+1,
$oldi == 0
);
$n += intval($i / (count($output) + 1));
$i %= count($output) + 1;
array_splice($output,$i,0,array(IDN::utf8($n)));
$i++;
}
return implode("",$output);
}
public static function decodeIDN($name) {
// split it, parse it and put it back together
return
implode(
".",
array_map("IDN::decodePart",explode(".",$name))
);
}
}
echo IDN::decodeIDN($_SERVER['HTTP_HOST']);
?>
idn_to_utf8
(PHP 5 >= 5.3.0, PECL intl >= 1.0.2, PECL idn >= 0.1)
idn_to_utf8 — Convierte un nombre de dominio de IDNA ASCII a Unicode
Descripción
Estilo por procedimientos
$domain
[, int $options = 0
[, int $variant = INTL_IDNA_VARIANT_2003
[, array &$idna_info
]]] )Esta función convierte un nombre de dominio Unicode de un formato compatible con IDNA ASCII a Unicode plano, codificado en UTF.8.
Parámetros
-
domain -
Dominio a convertir en formato IDNA ASCII-compatible.
-
options -
Opciones de conversión - combinación de constantes IDNA_* (excepto las constantes IDNA_ERROR_*).
-
variant -
INTL_IDNA_VARIANT_2003para IDNA 2003 oINTL_IDNA_VARIANT_UTS46para UTS #46. -
idna_info -
Este parámetro sólo se puede usar si
INTL_IDNA_VARIANT_UTS46se utilizó paravariant. En este caso, será llenado con un array con las claves 'result', la posibilidad de un resultado ilegal de la transformación, 'isTransitionalDifferent', un booleano indicando si el uso de los mecanismos de transición de UTS #46 ha cambiado o debería haber cambiado el resulado, y 'errors', que es de tipo int y representa un conjunto de bits de las constantes de error IDNA_ERROR_*.
Valores devueltos
Un nombre de dominio en Uniconde, codificado en UTF-8. o FALSE en caso de error
Historial de cambios
| Versión | Descripción |
|---|---|
| 5.4.0/PECL 2.0.0b1 |
Se añadieron los parámetros variant y
idna_info; y el soporte para UTS #46.
|
Ejemplos
Ejemplo #1 Ejemplo de idn_to_utf8()
<?php
echo idn_to_utf8('xn--tst-qla.de');
?>
El resultado del ejemplo sería:
täst.de
