2010-05-04 38 views
13

Tôi đang cố gắng giải mã dấu gạch ngang được mã hóa từ thực thể số thành chuỗi, nhưng có vẻ như tôi không thể tìm thấy một hàm có thể làm điều này đúng cách.Cách giải mã các thực thể HTML số trong PHP

Điều tốt nhất tôi thấy là mb_decode_numericentity(), tuy nhiên, vì một số lý do, nó không giải mã được dấu gạch ngang dài và một số ký tự đặc biệt khác.

$str = '–'; 

$str = mb_decode_numericentity($str, array(0xFF, 0x2FFFF, 0, 0xFFFF), 'ISO-8859-1'); 

Điều này sẽ trả về "?".

Bất kỳ ai biết cách giải quyết vấn đề này?

+3

Dấu gạch ngang dài có trong ISO-8859-1 không? –

+1

@ColShrapnel: Thật vậy là không. Nó có mặt trong Windows cp1252, tương tự, nhưng không phải là ISO-8859-1. Tốt hơn: sử dụng UTF-8. – bobince

+1

Chắc chắn, không có dấu gạch ngang dài trong ISO/IEC 8859-1 (Latin-1). Trên thực tế, đây là một ký tự unicode, và sử dụng UTF-8 đã giúp. Đó là lỗi của tôi mà tôi quên thay đổi mã hóa trong trình duyệt. Cảm ơn tất cả mọi người! – Yuriy

Trả lời

1

mb_decode_numericentity không xử lý thập lục phân, chỉ thập phân. Bạn có được kết quả mong đợi với:

$str = '–'; 

$str = mb_decode_numericentity ($str , Array(255, 3145727, 0, 65535) , 'ISO-8859-1'); 

Bạn có thể sử dụng hexdec để chuyển đổi số thập lục phân sang thập phân.

Ngoài ra, vì tò mò, hiện các công việc sau đây:

$str = '–'; 

$str = html_entity_decode($str); 
+0

Cảm ơn bạn đã trả lời nhanh, nhưng điều này trả về '?' cũng. – Yuriy

+0

> $ str = html_entity_decode ($ str); Đó là điều đầu tiên tôi thử. No. – Yuriy

+0

@Yuriy vui lòng bác bỏ hoặc xác nhận nhận xét của bạn về câu trả lời ** này ** sau khi bạn đã viết nhận xét cho câu hỏi ** này về lỗi của bạn. Tôi nghĩ 'html_entity_decode()' là giải pháp chính xác đơn giản nhất. – Apostle

19

Đoạn mã sau (chủ yếu là bị đánh cắp từ here và cải tiến) sẽ làm việc cho chữ, chữ số thập phân số, và các tổ chức hexa-thập phân số:

header("content-type: text/html; charset=utf-8"); 

/** 
* Decodes all HTML entities, including numeric and hexadecimal ones. 
* 
* @param mixed $string 
* @return string decoded HTML 
*/ 

function html_entity_decode_numeric($string, $quote_style = ENT_COMPAT, $charset = "utf-8") 
{ 
$string = html_entity_decode($string, $quote_style, $charset); 
$string = preg_replace_callback('~&#x([0-9a-fA-F]+);~i', "chr_utf8_callback", $string); 
$string = preg_replace('~&#([0-9]+);~e', 'chr_utf8("\\1")', $string); 
return $string; 
} 

/** 
* Callback helper 
*/ 

function chr_utf8_callback($matches) 
{ 
    return chr_utf8(hexdec($matches[1])); 
} 

/** 
* Multi-byte chr(): Will turn a numeric argument into a UTF-8 string. 
* 
* @param mixed $num 
* @return string 
*/ 

function chr_utf8($num) 
{ 
if ($num < 128) return chr($num); 
if ($num < 2048) return chr(($num >> 6) + 192) . chr(($num & 63) + 128); 
if ($num < 65536) return chr(($num >> 12) + 224) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128); 
if ($num < 2097152) return chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128); 
return ''; 
} 


$string ="&#x201D;"; 

echo html_entity_decode_numeric($string); 

Đề xuất cải tiến được hoan nghênh.

+0

Mặc dù ' không phải là tham chiếu thực thể html hợp lệ, nhưng không hiếm khi "tràn qua" từ tài liệu XML. Thêm các phần sau đây hoàn toàn không thấm nước: '$ string = str_ireplace ('''," '", $ string);' – Tilman

+2

Cải thiện khác: Mã này có rò rỉ bộ nhớ khủng khiếp. Mỗi lần điều này được gọi là hàm lambda mới được tạo ra với create_function() bị kẹt trong bộ nhớ. Có, hướng dẫn sử dụng trên preg_replace_callback() gợi ý rằng hàm lambda là một "ý tưởng tuyệt vời" để làm cho mã trông sạch hơn. Nhưng nó là sai. Không có gì sai khi tạo một hàm thực đơn giản 'hàm chr_utf8_callback ($ match) { \t trả về chr_utf8 (hexdec ($ match [1])); } 'và sử dụng nó thay vì' $ string = preg_replace_callback ('~ & # x ([0-9a-fA-F] +); ~ i', chr_utf8_callback, $ string); 'Mất bộ nhớ. – Tilman

+0

@Tilman điểm rất tốt, cố định, cảm ơn! –

Các vấn đề liên quan