2012-03-09 36 views
8

Tôi đang gặp một số vấn đề bằng cách sử dụng đoạn mã sau vào sử dụng đầu vào:Loại bỏ không hợp lệ/ký tự nhiều byte không đầy đủ

htmlentities($string, ENT_COMPAT, 'UTF-8'); 

Khi một ký tự multibyte không hợp lệ được phát hiện PHP ném một thông báo:

PHP Warning : htmlentities(): Chuỗi multibyte không hợp lệ trong đối số trong /path/to/file.php trên dòng 123

Suy nghĩ đầu tiên của tôi là ngăn chặn lỗi, nhưng đây là sl ow và nghèo thực hành: http://derickrethans.nl/five-reasons-why-the-shutop-operator-should-be-avoided.html

nghĩ thứ hai của tôi là sử dụng cờ ENT_IGNORE, nhưng ngay cả hướng dẫn PHP gợi ý không sử dụng này:

lặng lẽ bỏ chuỗi đơn vị mã không hợp lệ thay vì trả lại một chuỗi rỗng . Sử dụng cờ này không được khuyến khích vì nó »may have security implications.

Một chút lý do nữa khiến tôi đến đoạn mã sau:

// detect encoding 
$encoding = mb_detect_encoding($query); 
if($encoding != 'UTF-8') { 
    $query = mb_convert_encoding($query, 'UTF-8', $encoding); 
} else { 
    // strip out invalid utf8 sequences 
    $query = iconv('UTF-8', 'UTF-8//IGNORE', $query); 
} 

Thật không may iconv cũng ném một E_NOTICE khi nó loại bỏ/bỏ qua ký tự không hợp lệ:

Nếu bạn thêm chuỗi // TRANSLIT để chuyển ngữ out_charset được kích hoạt. Điều này có nghĩa là khi một ký tự không thể được biểu diễn trong bộ ký tự đích, nó có thể được xấp xỉ thông qua một hoặc nhiều ký tự trông giống nhau. Nếu bạn chắp thêm chuỗi // IGNORE, các ký tự không thể được biểu diễn trong bộ ký tự đích được loại bỏ âm thầm. Nếu không, str được cắt từ ký tự bất hợp pháp đầu tiên và E_NOTICE được tạo ra.

Vì vậy, về cơ bản tôi không còn lựa chọn nào ở đây. Tôi muốn sử dụng một thư viện đã thử và thử nghiệm để xử lý loại công cụ này hơn là cố gắng nó với một vài trong số các giải pháp dựa trên biểu thức chính quy mà tôi đã nhìn thấy trôi nổi xung quanh.

Vì vậy, dẫn tôi đến câu hỏi cuối cùng: Làm cách nào để xóa các ký tự nhiều byte không hợp lệ, hiệu quả, bảo mật mà không có thông báo/cảnh báo/lỗi?

+4

Nếu bạn không muốn sử dụng 'ENT_IGNORE', bạn cũng không muốn sử dụng' // IGNORE'. Họ làm điều tương tự và có cùng một ý nghĩa bảo mật. Đây có thể là một điểm rõ ràng và một cách tiếp cận lười biếng nhưng ... * bạn không nên giấu những lỗi này trong sản xuất sao? *? Điểm của những tình huống này là 'E_NOTICE' để quản trị viên máy chủ biết các vấn đề tiềm ẩn với máy chủ - các ký tự không hợp lệ sẽ chỉ xuất hiện nếu ai đó gửi chúng độc hại hoặc một số dữ liệu bị hỏng, cả hai đều yêu cầu quản trị viên chú ý. Đó là một trường hợp cực kỳ cạnh tranh ở mức nào. – DaveRandom

+0

Có * từ chối * mã hóa UTF-8 không hợp lệ một tùy chọn không? Nếu nó bị hỏng, có lẽ bạn không nên sử dụng nó để bắt đầu. – deceze

+0

Dave, vâng các lỗi bị ẩn, nhưng chúng tôi đang xem chúng trong nhật ký. Đó là một trường hợp cạnh mà một người nào đó đã gửi params xấu cho một lý do này hay cách khác. – Dean

Trả lời

2

Làm cách nào để xóa các ký tự nhiều byte không hợp lệ, hiệu quả, bảo mật mà không có thông báo/cảnh báo/lỗi?

Vâng, như bạn đã nêu trong câu hỏi của mình (or at least linked), việc xóa chuỗi byte không hợp lệ không phải là một tùy chọn.

Thay vào đó, có thể thay thế bằng ký tự thay thế U + FFFD. Kể từ PHP 5,4.0, bạn có thể sử dụng cờ ENT_SUBSTITUTE cho htmlentities. Đó có lẽ là an toàn nhất nếu bạn không muốn từ chối chuỗi.

iconv sẽ luôn cung cấp cho bạn cảnh báo trong các phiên bản PHP gần đây nếu không xóa cả chuỗi. Vì vậy, nó không giống như một lựa chọn tốt cho bạn.

4

iconv('UTF-8', "ISO-8859-1//IGNORE", $string);

làm việc rất tốt cho tôi. Dường như không tạo ra bất kỳ thông báo nào.

+1

+1 Tôi đã sử dụng: 'iconv (' UTF-8 ',' ASCII // TRANSLIT ', $ var)' và IGNORE thay vì TRANSLIT đã sửa thông báo 'các ký tự không hợp lệ' và xóa các biểu tượng cảm xúc không mong muốn khỏi chuỗi. –

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