2010-06-09 15 views
15

Я хочу, чтобы преобразовать этот [email protected] вКак преобразовать все символы в их HTML сущности эквивалента с использованием PHP

hello@domain.com 

Я пробовал:

url_encode($string) 

это обеспечивает ту же строку, я вошел, вернулся с символ @ преобразуется в %40

также попытался:

htmlentities($string) 

это обеспечивает ту же строку справа.

Я использую кодировку UTF8. не уверен, если это делает разницу ....

+0

Лей Я удалил свой ответ, потому что я понял, что это не хорошо. (Спасибо Artefacto), однако на самом деле это не является достаточной защитой от спам-ботов .... –

+0

Я знаю, что это не полностью надежный, однако у меня были хорошие результаты, используя эту функцию в прошлом, кодируя мой адрес электронной почты с помощью онлайн-сервисов. Теперь я пытаюсь создать его в CMS, который я создаю. – Ash

ответ

39

Вот он идет (предполагается, что UTF-8, но это тривиально изменить):

function encode($str) { 
    $str = mb_convert_encoding($str , 'UTF-32', 'UTF-8'); //big endian 
    $split = str_split($str, 4); 

    $res = ""; 
    foreach ($split as $c) { 
     $cur = 0; 
     for ($i = 0; $i < 4; $i++) { 
      $cur |= ord($c[$i]) << (8*(3 - $i)); 
     } 
     $res .= "&#" . $cur . ";"; 
    } 
    return $res; 
} 

EDIT Рекомендуемая альтернатива использования unpack:

function encode2($str) { 
    $str = mb_convert_encoding($str , 'UTF-32', 'UTF-8'); 
    $t = unpack("N*", $str); 
    $t = array_map(function($n) { return "&#$n;"; }, $t); 
    return implode("", $t); 
} 
+0

Ницца. --------- –

+0

Нет необходимости печатать $ cur как unsigned при преобразовании в строку в '$ res. =" & # ". $ cur. ";"; 'потому что диапазон символов Юникода не заходит так далеко. Однако, если у вас есть некорректная последовательность UTF-8, это может дать отрицательные значения (я не знаю, проверяет ли mb_convert_encoding диапазон). – Artefacto

+0

Это блестящий ответ по трем причинам: 1. Я не мог думать об этом сам. 2. Является элегантным и хорошо работает, 3. Я узнал от него много хорошего. Благодарю. – Ash

8

Гораздо более простой способ сделать это:

function convertToNumericEntities($string) { 
    $convmap = array(0x80, 0x10ffff, 0, 0xffffff); 
    return mb_encode_numericentity($string, $convmap, "UTF-8"); 
} 

Вы можете изменить кодировку, если используете что-то другое.

  • Исправлена ​​дальность действия карты. Благодаря Artefacto.
+0

Ничего, я не тестировал, но, полагаю, вам также нужно изменить карту, чтобы охватить все символы Юникода. – Artefacto

+0

Возможно, что-то вроде '$ convmap = array (0x000000, 0x10ffff, 0, 0xffffff);' (untested) – Artefacto

+0

В этом комментарии работает convmap: http://www.php.net/manual/en/function.mb-encode -numericentity.php # 88586 – koen

1
function uniord($char) { 

    $k=mb_convert_encoding($char , 'UTF-32', 'UTF-8'); 

    $k1=ord(substr($k,0,1)); 

    $k2=ord(substr($k,1,1)); 

    $value=(string)($k2*256+$k1); 

    return $value; 

} 

выше функция работает на 1 символ, но если у вас есть строка, вы можете сделать, как этот

$string="anytext"; 

$arr=preg_split(//u,$string,-1,PREG_SPLIT_NO_EMPTY); 

$temp=" "; 

foreach($arr as $v){ 

    $temp="&#".uniord($v);//prints the equivalent html entity of string 

}