2012-12-06 35 views
41

Kể từ php 5.4 html_entity_decode giới thiệu Bốn lá cờ mới, với một lời giải thích tối thiểuTrình chỉnh sửa ENT_HTML5, ENT_HTML401, ... trên html_entity_decode làm gì?

ENT_HTML401 Handle code as HTML 4.01. 
ENT_XML1 Handle code as XML 1. 
ENT_XHTML Handle code as XHTML. 
ENT_HTML5 Handle code as HTML 5. 

Tôi muốn hiểu được những gì họ cho. Trong trường hợp nào chúng quan trọng? Tôi đoán, (nhưng tôi có thể sai) là bất kỳ tiêu chuẩn khác, mã hóa một số ký tự không bình thường nhưng bất kỳ ký tự nào khác thì không, do đó, để tôn trọng điều đó, chúng ở đây.

Nghiên cứu của tôi: htmlentities có cùng một giải thích tối thiểu, không có ví dụ nào. Tôi đã googled không có may mắn.

+1

Trường hợp sử dụng thực sự khá đơn giản: sử dụng cờ thích hợp tùy thuộc vào phương ngữ XML/HTML bạn đang đặt giá trị vào. Tuy nhiên, câu hỏi này đặt ra là: sự khác nhau giữa các quy tắc thoát khỏi phương ngữ HTML/XML là gì? Đó là một câu hỏi hay. – deceze

+0

cảm ơn @deceze, trong trường hợp cụ thể của tôi, (do tác giả là như vậy) những gì được khai báo và văn bản được kiểm tra nhiều lần chưa từng có. Tôi đang điều tra những lá cờ này để xem họ có thể giúp gì không. –

Trả lời

73

Tôi bắt đầu tự hỏi những hành vi này hằng số có khi tôi nhìn thấy các hằng số tại trang htmlspecialchars. Tài liệu này là rác, vì vậy tôi bắt đầu đào sâu trong mã nguồn của PHP.

Về cơ bản, các hằng số này ảnh hưởng đến việc một số thực thể nhất định có được mã hóa hay không (hoặc được giải mã cho html_entity_decode). Hiệu ứng rõ ràng nhất là liệu dấu nháy đơn (') được mã hóa thành ' (cho ENT_HTML401) hoặc ' (đối với những người khác). Tương tự, nó xác định xem ' có được giải mã hay không khi sử dụng html_entity_decode. (' luôn được giải mã).

Tất cả các tập quán có thể được tìm thấy trong ext/standard/html.c và tệp tiêu đề của nó. Từ ext/tiêu chuẩn/html.h:

#define ENT_HTML_DOC_HTML401   0 
#define ENT_HTML_DOC_XML1      16 
#define ENT_HTML_DOC_XHTML      32 
#define ENT_HTML_DOC_HTML5      (16|32) 

(thay thế ENT_HTML_DOC_ bởi ENT_ để có được PHP họ tên không đổi)

tôi bắt đầu tìm kiếm cho tất cả các lần xuất hiện của những hằng số, và có thể chia sẻ sau đây trên hành vi của các hằng số ENT_*:

  • Nó ảnh hưởng đến thực thể số nào sẽ được giải mã hay không. Ví dụ:  được giải mã thành ký tự không đọc được/không hợp lệ cho ENT_HTML401ENT_XHTMLENT_XML1. Tuy nhiên, đối với ENT_HTML5, đây được coi là ký tự không hợp lệ và do đó nó vẫn là . (C function unicode_cp_is_allowed)
  • Với ENT_SUBSTITUTE bật, trình tự đơn vị mã không hợp lệ cho bộ ký tự được chỉ định được thay thế bằng . (không phụ thuộc vào loại tài liệu!)
  • Với ENT_DISALLOWED bật, mã số không được phép đối với loại tài liệu được chỉ định được thay thế bằng . (Không phụ thuộc vào charset!)
  • Với ENT_IGNORE, trình tự đơn vị mã không hợp lệ tương tự từ ENT_SUBSTITUTE được loại bỏ và không thay thế được thực hiện (phụ thuộc vào sự lựa chọn của "loại tài liệu", ví dụ như ENT_HTML5)
  • Disallow 
 cho ENT_HTML5 (line 976)
  • ENT_XHTML chia sẻ bản đồ thực thể với ENT_HTML401.Sự khác biệt duy nhất là ' sẽ được chuyển đổi sang một dấu nháy đơn với ENT_XHTML khi ENT_HTML401 không chuyển đổi nó (xem this line)
  • ENT_HTML401ENT_XHTML sử dụng chính xác bản đồ thực thể giống nhau (trừ phần chênh lệch từ quan điểm trước đó). ENT_HTML5 sử dụng bản đồ của riêng nó. Những người khác (hiện tại là ENT_XML1) có bản đồ giải mã rất hạn chế (>, &, <, ', " và số tương đương của chúng). (xem C function unescape_inverse_map)
  • Lưu ý cho điểm trước đó: khi chỉ có một vài thực thể phải được thoát (nghĩ về htmlspecialchars), tất cả bản đồ thực thể sẽ sử dụng cùng một địa chỉ là ENT_XML1, ngoại trừ ENT_HTML401. Người đó sẽ không sử dụng ', nhưng '.

Điều đó bao gồm hầu hết mọi thứ. Tôi sẽ không liệt kê tất cả các sự khác biệt của thực thể, thay vào đó tôi muốn trỏ đến https://github.com/php/php-src/tree/php-5.4.11/ext/standard/html_tables đối với một số tệp văn bản chứa ánh xạ cho từng loại.

Tôi nên sử dụng ENT_ * nào cho htmlspecialchars?

Khi sử dụng htmlspecialchars với ENT_COMPAT (mặc định) hoặc ENT_NOQUOTES, không quan trọng bạn chọn loại nào (xem bên dưới). Tôi thấy một số câu trả lời ở đây trên SO rằng nắm này:

<input value="<?php echo htmlspecialchars($str, ENT_HTML5);?>" > 

Đây là không an toàn. Nó sẽ ghi đè lên giá trị mặc định ENT_HTML401 | ENT_COMPAT có sự khác biệt mà các thực thể HTML5 được sử dụng, nhưng cũng là rằng dấu ngoặc kép không được thoát nữa! Ngoài ra, đây là mã dự phòng. Đối tượng mà phải được mã hóa bởi htmlspecialchars đều giống nhau cho tất cả ENT_HTML401, ENT_HTML5 vv

Chỉ cần sử dụng ENT_COMPAT hoặc ENT_QUOTES để thay thế. Sau này cũng hoạt động khi bạn sử dụng dấu nháy đơn cho các thuộc tính (value='foo'). Nếu bạn chỉ có hai đối số cho htmlspecialchars, không bao gồm đối số vì nó là mặc định (ENT_HTML401 là 0, hãy nhớ?).

Khi bạn muốn in một cái gì đó trên trang (giữa các thẻ, không phải thuộc tính), nó không quan trọng ở tất cả những gì bạn chọn vì nó sẽ có tác dụng như nhau. Nó thậm chí còn đủ để sử dụng ENT_NOQUOTES | ENT_HTML401 bằng với giá trị số 0.

Xem thêm bên dưới, về ENT_SUBTITUTE và ENT_DISALLOWED.

Tôi nên sử dụng ENT_ * nào cho htmlentities?

Nếu trình soạn thảo văn bản hoặc cơ sở dữ liệu của bạn quá yếu đến nỗi bạn không thể bao gồm các ký tự không phải là US-ASCII (ví dụ: UTF-8), bạn có thể sử dụng htmlentities. Nếu không, hãy lưu một số byte và sử dụng htmlspecialchars (xem ở trên).

Cho dù bạn cần sử dụng ENT_HTML401, ENT_HTML5 hoặc thứ gì đó khác tùy thuộc vào cách trang của bạn được phân phát. Khi bạn có trang HTML5 (<!doctype html>), hãy sử dụng ENT_HTML5. XHTML hoặc XML? Sử dụng ENT_XHTML hoặc ENT_XML1 tương ứng. Không có tài liệu hoặc HTML đơn giản 'HTML4, hãy sử dụng ENT_HTML401 (đây là mặc định khi bị bỏ qua).

Tôi có nên sử dụng ENT_DISALLOWED, ENT_IGNORE hoặc ENT_SUBSTITUTE không?

Theo mặc định, các chuỗi byte không hợp lệ cho bộ ký tự đã cho bị xóa. Để có một ở vị trí của một chuỗi byte không hợp lệ, xác định ENT_SUBSTITUTE. (Lưu ý rằng &#FFFD; được hiển thị cho không phải UTF-8 bảng mã). Khi bạn xác định ENT_IGNORE Mặc dù vậy, những nhân vật này không được hiển thị ngay cả khi bạn chỉ định ENT_SUBSTITUTE.

Ký tự không hợp lệ cho loại tài liệu được thay thế bởi cùng một ký tự thay thế (hoặc thực thể của nó) ở trên khi ENT_DISALLOWED được chỉ định. Điều này xảy ra bất kể có tập hợp ENT_IGNORE (không liên quan gì đến các ký tự không hợp lệ đối với các loại tài liệu).

+5

Wow, PHP đã thực sự quản lý để vít lên này. Câu trả lời tuyệt vời mặc dù! – Mahn

+1

Xin lưu ý rằng mặc dù doc không khuyến khích sử dụng ENT_IGNORE cho các tác động bảo mật (http://php.net/manual/en/function.htmlspecialchars.php), các const khác chỉ khả dụng bắt đầu từ PHP 5.4.0, trong khi ENT_IGNORE là đã có trong PHP 5.3.0. – JeromeJ