2008-10-06 47 views
25

Tôi có một biểu mẫu có văn bản. Người dùng nhập một khối văn bản được lưu trữ trong cơ sở dữ liệu.Làm cách nào để chuyển đổi từ dấu ngoặc kép thông minh và dấu gạch ngang trong chuỗi?

Thỉnh thoảng người dùng sẽ dán văn bản từ Word có dấu ngoặc kép thông minh hoặc các dấu gạch ngang. Các ký tự đó xuất hiện trong cơ sở dữ liệu dưới dạng: â € â € ™, â € œ, â €

Tôi nên gọi hàm nào trên chuỗi đầu vào là chuyển giá thông minh thành dấu ngoặc kép thường xuyên và dấu gạch ngang thường xuyên?

Tôi đang làm việc trong PHP.

Cập nhật: Cảm ơn tất cả các phản hồi tuyệt vời từ trước tới nay. Các trang trên trang web của Joel về mã hóa là rất nhiều thông tin: http://www.joelonsoftware.com/articles/Unicode.html

Một số lưu ý về môi trường của tôi:

Cơ sở dữ liệu MySQL đang sử dụng mã UTF-8. Tương tự như vậy, các trang HTML hiển thị nội dung đang sử dụng UTF-8 (Cập nhật :) bằng cách đặt rõ ràng loại nội dung meta.

Trên các trang đó, dấu ngoặc kép và các dấu gạch ngang thông minh xuất hiện dưới dạng hình thoi với dấu chấm hỏi.

Giải pháp:

Cảm ơn bạn đã trả lời. Giải pháp được gấp đôi:

  1. Đảm bảo rằng cơ sở dữ liệu và tệp HTML được đặt rõ ràng để sử dụng mã hóa UTF-8.
  2. Sử dụng htmlspecialchars() thay vì htmlentities().

Trả lời

1

Chúng tôi thường sử dụng các hàm thay thế chuỗi tiêu chuẩn cho điều đó. Mặc dù bản chất của ASCII/Unicode trong bối cảnh đó là khá u ám, nó hoạt động. Chỉ cần đảm bảo tệp php của bạn được lưu ở định dạng mã hóa phù hợp, v.v.

4

Có vẻ như vấn đề thực sự là cơ sở dữ liệu của bạn không sử dụng cùng một mã hóa ký tự làm trang của bạn (có thể là UTF-8). Trong trường hợp đó, nếu bất kỳ người dùng nào gửi một ký tự không phải ASCII, bạn có thể sẽ thấy các ký tự lạ trong cơ sở dữ liệu. Tìm kiếm và sửa chữa chỉ một vài trong số họ (dấu ngoặc kép và dấu gạch ngang) sẽ không giải quyết được vấn đề thực sự.

Dưới đây là một số thông tin về migrating your database to another character encoding, ít nhất là cho cơ sở dữ liệu MySQL.

1

Theo kinh nghiệm của tôi, việc chấp nhận báo giá thông minh dễ dàng hơn và đảm bảo bạn đang sử dụng cùng một mã hóa ở mọi nơi. Để bắt đầu, hãy thêm thẻ này vào thẻ biểu mẫu của bạn: accept-charset="utf-8"

1

Bạn có thể thử mb_ convert_encoding từ ISO-8859-1 đến UTF-8.

$str = mb_convert_encoding($str, 'UTF-8', 'ISO-8859-1'); 

Giả định bạn muốn UTF-8 và chuyển đổi có thể tìm thấy các thay thế hợp lý ... nếu không, hãy tự mình làm hoặc tự mình thay thế chúng.

2

Đây là một sự cố không may quá phổ biến, không được hỗ trợ bởi việc xử lý các ký tự rất kém của PHP.

gì chúng tôi làm là buộc các văn bản thông qua iconv

// Convert input data to UTF8, ignore any odd (MS Word..) chars 
// that don't translate 
$input = iconv("ISO-8859-1","UTF-8//IGNORE",$input); 

Các //IGNORE cờ có nghĩa là bất cứ điều gì mà không thể được dịch sẽ được vứt bỏ.

Nếu bạn nối chuỗi // IGNORE, các ký tự không thể được biểu diễn trong bộ ký tự đích được bỏ qua âm thầm.

+1

Điều này có vẻ như một "sửa chữa nhanh" hoàn hảo như vậy nhưng đáng buồn là nó làm cho trường hợp thử nghiệm của tôi tồi tệ hơn đáng kể bằng cách thêm * nhiều * ký tự không hợp lệ. –

+4

Chuyển đổi từ tiếng Latinh 1 sang UTF-8 chỉ có ý nghĩa nếu bạn * biết * rằng bộ ký tự đầu vào là tiếng Latinh 1. Nhưng nếu đầu vào đã là UTF-8, bạn sẽ chỉ thêm nó bằng cách "dịch" nó từ tiếng Latin 1 với UTF-8 lần thứ hai. –

9

Cơ sở dữ liệu mysql đang sử dụng mã hóa UTF-8 . Tương tự, các trang html hiển thị nội dung đang sử dụng UTF-8.

Nội dung của HTML có thể bằng UTF-8, có, nhưng bạn đặt rõ ràng loại nội dung (mã hóa) của các trang HTML (được tạo thông qua PHP?) Sang UTF-8 không? Hãy thử trở lại một tiêu đề Content-Type của "text/html;charset=utf-8" hoặc thêm <meta> thẻ để HTMLs của bạn:

<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> 

Bằng cách đó, các kiểu nội dung của dữ liệu trình PHP cũng sẽ giống nhau.

Tôi gặp sự cố tương tự và thêm thẻ <meta> đã hoạt động cho tôi.

0

Đây có thể không phải là giải pháp tốt nhất, nhưng tôi sẽ thử nghiệm để tìm hiểu xem PHP thấy gì. Giả sử nó thấy "-" (có một vài khả năng khác, như đơn giản "" "hoặc có thể" & # 8220; "). Sau đó, làm một str_replace để loại bỏ tất cả những cái đó và thay thế chúng bằng dấu ngoặc kép bình thường, trước khi nhồi nhét câu trả lời trong cơ sở dữ liệu.

Giải pháp tốt hơn có thể liên quan đến việc làm cho dữ liệu đầu cuối vượt qua tất cả UTF-8, vì mọi người đang cố gắng trợ giúp trong các câu trả lời khác.

1

Bạn phải chắc chắn kết nối cơ sở dữ liệu của mình được định cấu hình để chấp nhận và cung cấp UTF-8 từ và cho ứng dụng khách (nếu không nó sẽ chuyển thành "mặc định", thường là latin1).

Trong thực tế, điều này có nghĩa là chạy truy vấn SET NAMES 'utf8';

http://www.phpwact.org/php/i18n/utf-8/mysql

Ngoài ra, dấu ngoặc kép thông minh là một phần của bộ ký tự windows-1252, không iso-8859-1 (latin-1). Không liên quan lắm đến vấn đề của bạn, nhưng chỉ là FYI. Biểu tượng đồng euro cũng ở trong đó.

1

sự cố nằm trên bộ ký tự mysql, tôi đã khắc phục sự cố của mình với dòng mã này.

mysql_set_charset('utf8',$link); 
+0

Điều này làm việc cho tôi là tốt, thêm trực tiếp trên truy vấn chạy 'INSERT' /' UPDATE'. Mọi thứ khác được đặt thành UTF8 đúng cách, bảng ký tự bảng, các collations cột, trang đầu ra HTML. Vui mừng điều này cuối cùng đã làm các trick! – purefusion

1

Bạn phải thay đổi cách đối chiếu các cột riêng lẻ thành UTF8; thay đổi cơ sở dữ liệu nói chung sẽ không làm thay đổi chúng.

1

Nếu bạn đang tìm kiếm để thoát khỏi những nhân vật này cho các trang web trong khi giữ gìn xuất hiện của họ, do dây của bạn sẽ xuất hiện như thế này: “Thật tuyệt!” hơn "Đó là nhàm chán" ...

bạn có thể làm điều này bằng cách sử dụng chức năng tùy chỉnh htmlEncode riêng của bạn ở vị trí của htmlentities PHP():

$trans_tbl = false; 

function htmlEncode($text) { 

    global $trans_tbl; 

    // create translation table once 
    if(!$trans_tbl) { 
    // start with the default set of conversions and add more. 

    $trans_tbl = get_html_translation_table(HTML_ENTITIES); 

    $trans_tbl[chr(130)] = '&sbquo;'; // Single Low-9 Quotation Mark 
    $trans_tbl[chr(131)] = '&fnof;'; // Latin Small Letter F With Hook 
    $trans_tbl[chr(132)] = '&bdquo;'; // Double Low-9 Quotation Mark 
    $trans_tbl[chr(133)] = '&hellip;'; // Horizontal Ellipsis 
    $trans_tbl[chr(134)] = '&dagger;'; // Dagger 
    $trans_tbl[chr(135)] = '&Dagger;'; // Double Dagger 
    $trans_tbl[chr(136)] = '&circ;'; // Modifier Letter Circumflex Accent 
    $trans_tbl[chr(137)] = '&permil;'; // Per Mille Sign 
    $trans_tbl[chr(138)] = '&Scaron;'; // Latin Capital Letter S With Caron 
    $trans_tbl[chr(139)] = '&lsaquo;'; // Single Left-Pointing Angle Quotation Mark 
    $trans_tbl[chr(140)] = '&OElig;'; // Latin Capital Ligature OE 

    // smart single/ double quotes (from MS) 
    $trans_tbl[chr(145)] = '&lsquo;'; 
    $trans_tbl[chr(146)] = '&rsquo;'; 
    $trans_tbl[chr(147)] = '&ldquo;'; 
    $trans_tbl[chr(148)] = '&rdquo;'; 

    $trans_tbl[chr(149)] = '&bull;'; // Bullet 
    $trans_tbl[chr(150)] = '&ndash;'; // En Dash 
    $trans_tbl[chr(151)] = '&mdash;'; // Em Dash 
    $trans_tbl[chr(152)] = '&tilde;'; // Small Tilde 
    $trans_tbl[chr(153)] = '&trade;'; // Trade Mark Sign 
    $trans_tbl[chr(154)] = '&scaron;'; // Latin Small Letter S With Caron 
    $trans_tbl[chr(155)] = '&rsaquo;'; // Single Right-Pointing Angle Quotation Mark 
    $trans_tbl[chr(156)] = '&oelig;'; // Latin Small Ligature OE 
    $trans_tbl[chr(159)] = '&Yuml;'; // Latin Capital Letter Y With Diaeresis 

    ksort($trans_tbl); 
    } 

    // escape HTML  
    return strtr($text, $trans_tbl); 
} 
0

Trên thực tế vấn đề không xảy ra trong PHP nhưng nó đang xảy ra trong JavaScript, đó là do sao chép/dán từ Word, vì vậy bạn cần giải quyết vấn đề của mình trong JavaScript trước khi bạn chuyển văn bản sang PHP, Vui lòng xem câu trả lời https://stackoverflow.com/a/6219023/1857295.

+0

vui lòng thêm phần liên quan của câu trả lời. – Robert

+0

@ Robert nói rằng "Tôi có một biểu mẫu với một vùng văn bản. Người dùng nhập một khối văn bản được lưu trữ trong cơ sở dữ liệu", vì vậy tôi tin rằng điều đó có nghĩa là anh ta sử dụng JavaScript để truyền dữ liệu từ phía trước (tức là trình duyệt) đến phía máy chủ (tức là PHP). Ông cũng nói "dán văn bản từ Word", "Tôi nên gọi hàm nào trên chuỗi đầu vào" có nghĩa là trước khi dữ liệu nhập vào MySQL, do đó sử dụng giải pháp đó sẽ tránh được những ký tự lạ trong cơ sở dữ liệu. –

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