Đầu ra PHP hiển thị những viên kim cương đen nhỏ với dấu chấm hỏi


81

Tôi đang viết một chương trình php lấy từ một nguồn cơ sở dữ liệu. Một số véc-tơ có dấu ngoặc kép hiển thị dưới dạng kim cương đen với dấu chấm hỏi trong đó ( , KÝ TỰ THAY THẾ , tôi giả sử từ văn bản Microsoft Word).

Làm cách nào để sử dụng php để loại bỏ các ký tự này?


1
Đừng tước bỏ chúng, hãy sửa thời gian. Xem thêm "kim cương đen" trong stackoverflow.com/questions/38363566/…
Rick James

Câu trả lời:


74

Nếu bạn nhìn thấy ký tự đó ( U + FFFD "KÝ TỰ THAY THẾ") thì điều đó thường có nghĩa là bản thân văn bản được mã hóa ở một số dạng mã hóa byte đơn nhưng được diễn giải theo một trong các mã hóa unicode (UTF8 hoặc UTF16).

Nếu nó theo cách khác, nó sẽ (thường) trông giống như thế này: ä.

Có thể mã hóa ban đầu là ISO-8859-1, còn được gọi là Latin-1. Bạn có thể kiểm tra điều này mà không cần phải thay đổi tập lệnh của mình: Các trình duyệt cung cấp cho bạn tùy chọn để diễn giải lại một trang bằng một kiểu mã hóa khác - trong Firefox, hãy sử dụng "Chế độ xem" -> "Mã hóa Ký tự".

Để làm cho trình duyệt sử dụng mã hóa chính xác, hãy thêm tiêu đề HTTP như sau:

header("Content-Type: text/html; charset=ISO-8859-1");

hoặc đặt mã hóa trong thẻ meta:

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

Ngoài ra, bạn có thể thử đọc từ cơ sở dữ liệu bằng một mã hóa khác (tốt nhất là UTF-8) hoặc chuyển đổi văn bản bằng iconv().


Cho đến nay đây là giải pháp gần nhất. Tuy nhiên, bây giờ tôi có một meta: <meta http-equiv = "Content-Type" content = "text / html; charset = UTF-8"> và tôi đang sử dụng iconv để chuyển đổi từ iso-8859-1 sang utf- 8, các charecters bây giờ hiển thị dưới dạng một hộp với 0096 và 0092 respectivley đặc biệt ('hoặc -) bất kỳ suy nghĩ nào khác?

vâng, tôi có một suy nghĩ khác: làm một số bài tập về nhà ... có thể bạn đã sử dụng sai mã nguồn. 0x92 và 0x96 là "dấu ngoặc kép cong" và "dấu gạch ngang" trong windows-1252. đó có thể là một trong những quyền? bạn đã thử thủ thuật trình duyệt chưa?

Tiêu đề PHP đã khắc phục sự cố cho tôi khi sử dụng lớp PDF2Text.
James P.

Không nên header("Content-Type: text/plain; charset=ISO-8859-1");header("Content-Type: text/html; charset=ISO-8859-1");?
j08691

@ j08691: à, điều đó phụ thuộc vào loại nội dung bây giờ phải không?

41

Đây là một vấn đề về bộ ký tự. Do đó, nó có thể bị sai ở nhiều cấp độ khác nhau, nhưng rất có thể, các chuỗi trong cơ sở dữ liệu của bạn được mã hóa utf-8 và bạn đang trình bày chúng dưới dạng iso-8859-1. Hoặc cách khác xung quanh.

Cách thích hợp để khắc phục sự cố này là chỉnh sửa các bộ nhân vật của bạn. Chiến lược đơn giản nhất, vì bạn đang sử dụng PHP, là sử dụng iso-8859-1 trong toàn bộ ứng dụng của bạn. Để làm điều này, bạn phải đảm bảo rằng:

  • Tất cả các tệp nguồn PHP được lưu dưới dạng iso-8859-1 (Không nên nhầm lẫn với cp-1252).
  • Máy chủ web của bạn được định cấu hình để phân phát tệp với charset=iso-8859-1
  • Ngoài ra, bạn có thể ghi đè cài đặt máy chủ web từ bên trong tài liệu PHP bằng cách sử dụng header.
  • Ngoài ra, bạn có thể chèn thẻ meta vào HTML của mình, thẻ này chỉ định điều tương tự, nhưng điều này không hoàn toàn cần thiết.
  • Bạn cũng có thể chỉ định accept-charsetthuộc tính trên các <form>phần tử của mình .
  • Các bảng cơ sở dữ liệu được xác định với mã hóa là latin1
  • Kết nối cơ sở dữ liệu giữa PHP tới và cơ sở dữ liệu được đặt thành latin1

Nếu bạn đã có dữ liệu trong cơ sở dữ liệu của mình, bạn nên biết rằng chúng có thể đã bị xáo trộn. Nếu bạn chưa ở trong giai đoạn sản xuất, chỉ cần xóa tất cả và bắt đầu lại. Nếu không, bạn sẽ phải thực hiện một số thao tác dọn dẹp dữ liệu.

Một lưu ý về thẻ meta, vì mọi người đều hiểu nhầm chúng là gì:

Khi máy chủ web phân phát một tệp (Tài liệu HTML), nó sẽ gửi một số thông tin, thông tin này không được hiển thị trực tiếp trong trình duyệt. Đây được gọi là tiêu đề HTTP. Một trong những tiêu đề như vậy, là Content-Typetiêu đề, chỉ định kiểu mimetype của tệp (Ví dụ text/html:) cũng như mã hóa (hay còn gọi là bộ ký tự). Mặc dù hầu hết các máy chủ web sẽ gửi một Content-Typetiêu đề với charsetthông tin, nhưng nó là tùy chọn. Nếu nó không xuất hiện, thay vào đó, trình duyệt sẽ diễn giải bất kỳ thẻ meta nào với http-equiv="Content-Type". Điều quan trọng là nhận ra rằng thẻ meta chỉ được hiểu nếu máy chủ web không gửi tiêu đề. Trong thực tế, điều này có nghĩa là nó chỉ được sử dụng nếu trang được lưu vào đĩa và sau đó được mở từ đó.

Trang này có một giải thích rất tốt về những điều này.


37

Tôi cũng phải đối mặt với vấn đề này. Trong khi đó, tôi gặp phải ba trường hợp mà nó đã xảy ra:

  1. substr ()

    Tôi đang sử dụng substr()trên một chuỗi UTF8 cắt các ký tự UTF8, do đó các ký tự cắt không thể được hiển thị chính xác. Sử dụng mb_substr($utfstring, 0, 10, 'utf-8');thay thế. Tín dụng

  2. htmlspecialchars ()

    Một sự cố khác đang sử dụng htmlspecialchars()trên chuỗi UTF8. Cách khắc phục là sử dụng:htmlspecialchars($utfstring, ENT_QUOTES, 'UTF-8');

  3. preg_replace ()

    Cuối cùng, tôi phát hiện ra rằng preg_replace()có thể dẫn đến các vấn đề với UTF. $string = preg_replace('/[^A-Za-z0-9ÄäÜüÖöß]/', ' ', $string);Ví dụ, mã đã chuyển đổi chuỗi UTF "F (×) = 2 × -3" thành "F 2 ". Cách khắc phục là sử dụng mb_ereg_replace()thay thế.

Tôi hy vọng thông tin bổ sung này sẽ giúp thoát khỏi những vấn đề như vậy.


2
Đó chính xác là vấn đề mà tôi đang phải đối mặt. Không biết về các hàm chuỗi mb.
Ren

1
Nó cũng xảy ra cho strtolowerchức năng. Tất cả các chức năng có liên quan trong hướng dẫn sử dụng PHP
micaball

13

Như đã đề cập trong các câu trả lời trước đó, nó xảy ra vì văn bản của bạn đã được ghi vào cơ sở dữ liệu ở dạng iso-8859-1mã hóa hoặc bất kỳ định dạng nào khác.

Vì vậy, bạn chỉ cần chuyển đổi dữ liệu thành utf8trước khi xuất ra.

$text = “string from database”;
$text = utf8_encode($text);
echo $text;

11

Để đảm bảo kết nối MYSQL của bạn được đặt thành UTF-8 (hoặc latin1, tùy thuộc vào những gì bạn đang sử dụng), bạn có thể thực hiện việc này để:

$con = mysql_connect("localhost","username","password");    
mysql_set_charset('utf8',$con);

hoặc sử dụng cái này để kiểm tra bộ ký tự bạn đang sử dụng:

$con = mysql_connect("localhost","username","password");   
$charset = mysql_client_encoding($con);
echo "The current character set is: $charset\n"; 

Thông tin thêm tại đây: http://php.net/manual/en/ Chức năng.mysql-set-charset.php


Điều này rất hữu ích và đã giải quyết được vấn đề mã hóa trích dẫn của tôi trong dữ liệu đến từ cơ sở dữ liệu MySQL từ xa, cảm ơn bạn!
khổ nạn

@ptwiggerl điều này đã giúp ích rất nhiều.
unixmiah

Tôi đã di chuyển một trang web sang một máy chủ khác và tôi gặp phải sự cố này, mysql_set_charset ('utf8', $ con); đã giải quyết nó!
Rafael Moni

5

Dựa trên mô tả của bạn về sự cố, dữ liệu trong cơ sở dữ liệu của bạn gần như chắc chắn được mã hóa dưới dạng Windows-1252 và trang của bạn gần như chắc chắn được cung cấp dưới dạng ISO-8859-1 . Hai bộ ký tự này tương đương nhau ngoại trừ Windows-1252 có 16 ký tự phụ không có trong ISO-8859-1, bao gồm cả dấu ngoặc kép trái và phải.

Giả sử phân tích của tôi là đúng, giải pháp đơn giản nhất là cung cấp trang của bạn dưới dạng Windows-1252. Điều này sẽ hoạt động vì tất cả các ký tự có trong ISO-8859-1 cũng có trong Windows-1252. Trong PHP, bạn có thể thay đổi mã hóa như sau:

header('Content-Type: text/html; charset=Windows-1252');

Tuy nhiên, bạn thực sự nên kiểm tra xem bạn đang sử dụng kiểu mã hóa ký tự nào trong các tệp HTML và nội dung của cơ sở dữ liệu, đồng thời chú ý đến sự nhất quán hoặc chuyển đổi đúng cách khi không thể thực hiện được.


Vấn đề với gợi ý này là rất có thể dữ liệu là sự kết hợp của các bộ ký tự khác nhau tại thời điểm này. Nếu bạn không biết chính xác điều gì đã xảy ra, nó chỉ trở nên lộn xộn hơn, nếu bạn chỉ ném một số bản sửa lỗi ngẫu nhiên vào chỗ này và chỗ khác.
troelskn

Tôi đồng ý. Tôi đã chỉnh sửa phần nào bài đăng của mình để phản ánh rằng giải pháp này không thể thay thế cho việc biết bạn đang làm gì. Tuy nhiên, tôi đã đi đến kết luận rằng hầu hết các nhà phát triển hoặc không có khả năng hiểu được vấn đề này, hoặc không quan tâm. Nó dường như đến ít nhất mỗi tháng một lần ở nơi tôi làm việc.
Daniel Cassidy

Đó là quan sát của tôi khá nhiều. Đối với những gì tôi quan tâm, họ gặt hái được như họ gieo. Nhưng bạn có thể đúng; Rất có thể dữ liệu của anh ta thực sự là cp-1252 .. Ít nhất một số là như vậy.
troelskn

Tôi đã thử một loạt các giải pháp cho cùng một vấn đề. Điều này ngay lập tức có hiệu quả với ít nỗ lực nhất
chuỗi sáu

4

Tôi đã chọn loại bỏ các ký tự này ra khỏi chuỗi bằng cách thực hiện điều này -

ini_set('mbstring.substitute_character', "none"); 
$text= mb_convert_encoding($text, 'UTF-8', 'UTF-8');

1
Điều này thật tuyệt vời, nó hoạt động với tôi, đã thử utf8_encode và ut8_decode cũng- không hoạt động. Nhưng giải pháp này đã hoạt động trong trường hợp của tôi. Cảm ơn bạn.
sanjeev shetty

4

Thêm hàm này vào các biến utf8_encode của bạn ($ biến của bạn);


Xin vui lòng giải thích về câu trả lời này.
ppovoski

1
đây là chức năng cho phép bạn để loại bỏ các ký tự đặc biệt và lợi nhuận cho bạn những tiêu chuẩn utf8 của nhân vật google.com/...
rk_programmer

Điều này làm việc với các phân số không được hiển thị chính xác.
Rog

Theo tôi, đây nên là một câu trả lời được chấp nhận; đây là phương pháp duy nhất hiệu quả với tôi, tôi đã thử tất cả.
quantme

4

Chỉ cần dán mã này vào đầu trang.

<?php
header("Content-Type: text/html; charset=ISO-8859-1");
?>

Vui lòng bao gồm một giải thích ngắn gọn về chức năng của mã.
Hội trường CT

1
Mã php này Để Cho phép bộ ký tự "ISO-8859-1" và trong bộ ký tự này, biểu tượng này được hiển thị dưới dạng một ký tự.
Harshil Kaneria


3

Điều này sẽ giúp bạn. Đặt <head>thẻ bên trong này

<meta charset="iso-8859-1">

1

Điều đó có thể do unicode hoặc bộ ký tự khác không khớp. Thử thay đổi bộ ký tự trong trình duyệt của bạn, trong phần cài đặt, văn bản sẽ ổn. Sau đó, câu hỏi về cách chuyển đổi nội dung cơ sở dữ liệu của bạn thành bộ ký tự mà bạn sử dụng để hiển thị. (Thực ra có thể chỉ là thêm câu lệnh mã ký tự utf-8 vào đầu ra của bạn.)


1

những gì tôi đã làm cuối cùng sau khi tôi sửa các bảng của mình là sao lưu nó và thay đổi lại cài đặt thành utf-8, sau đó tôi thay đổi tệp kết xuất của mình để DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci là các mục đặt ký tự của tôi

bây giờ tôi không gặp vấn đề về bộ ký tự nữa vì cơ sở dữ liệu và trình duyệt là utf8.

Tôi đã tìm ra nguyên nhân gây ra nó. Đó là trang web + hiệu ứng trình duyệt trên DB. Trên các thiết bị đầu cuối là linux (ubuntu + firefox), nó đã mã hóa cơ sở dữ liệu bằng latin1, đó là những gì các tab được đặt. Nhưng trên các thiết bị đầu cuối của windows 10 + edge, các mục nhập được mã hóa thành utf8. Ngoài ra, tôi nhận thấy cửa sổ 10 có vấn đề với latin1 vì vậy tôi quyết định bẻ cong theo gió và chuyển đổi tất cả thành utf8.

Tôi nhận ra đó là sự cố của windows 10 vì chúng tôi bắt đầu sử dụng các thiết bị đầu cuối win 10. Vì vậy, một lần nữa lỗi microsoft lại gây ra vấn đề. Tôi vẫn không biết tại sao mã hóa thay đổi trên các biểu mẫu vì trình duyệt trong windows 10 hiển thị bộ ký tự latin1 nhưng khi nó chuyển sang dạng mã utf8 và tôi nhận được dữ liệu bất thường. nhưng trong linux + firefox nó không làm điều đó.


1

Điều này đã xảy ra để làm việc trong trường hợp của tôi:

$text = utf8_decode($text)

Tôi biến ký tự kim cương đen thành một dấu chấm hỏi để bạn có thể:

$text = str_replace('?', '', utf8_decode($text));

1
cảnh báo về các $text = phần: điều này sẽ thay đổi tất cả dấu hỏi trong chuỗi, không chỉ là kim cương
treyBake

1

Chỉ cần thêm những dòng này trước tiêu đề.

Định dạng chính xác của .doc/docxtệp sẽ được truy xuất:

 if(ini_get('zlib.output_compression'))

   ini_set('zlib.output_compression', 'Off');
 ob_clean();

0

Bạn cũng có thể thay đổi bộ ký tự trong trình duyệt của mình. Chỉ vì lý do gỡ lỗi.


0

Việc sử dụng cùng một bộ ký tự (như được đề xuất ở đây) trong cả cơ sở dữ liệu và HTML không phù hợp với tôi ... Vì vậy, hãy nhớ rằng mã được tạo dưới dạng HTML, tôi đã chọn sử dụng &quot;(HTML code) hoặc &#34;(ISO Latin-1 mã) trong văn bản cơ sở dữ liệu của tôi nơi các dấu ngoặc kép đã được sử dụng. Điều này đã giải quyết vấn đề trong khi cung cấp cho tôi một dấu ngoặc kép. Thật kỳ lạ khi lưu ý rằng trước giải pháp này, chỉ một số dấu ngoặc kép và dấu nháy đơn không hiển thị chính xác trong khi các dấu nháy đơn khác thì có, tuy nhiên, mã đặc biệt vẫn hoạt động trong mọi trường hợp.


0

Tôi đã chạy mã "phát hiện mã hóa" sau khi thay đổi đối chiếu của tôi trong phpmyadmin và bây giờ nó có tên là Latin_1.

nhưng đây là điều mà tôi đã gặp phải khi xem xét một dữ liệu bất thường khác trong ứng dụng của mình và cách tôi khắc phục nó:

Tôi vừa nhập một bảng có mã hóa hỗn hợp (với dấu chấm hỏi hình thoi ở một số dòng và tất cả đều nằm trong cùng một cột.) Vì vậy đây là mã sửa lỗi của tôi. Tôi đã sử dụng quy trình utf8_decode lấy trình giữ chỗ không xác định và chỉ định một dấu chấm hỏi đơn giản ở vị trí của "dấu chấm hỏi hình thoi", sau đó tôi sử dụng str_replace để thay thế dấu hỏi bằng dấu cách giữa các dấu ngoặc kép. đây là [mã]

    include 'dbconnectfile.php';

  //// the variable $db comes from my db connect file
   /// inx is my auto increment column
   /// broke_column is the column I need to fix

      $qwy = "select inx,broke_column from Table ";
      $res = $db->query($qwy); 

      while ($data = $res->fetch_row()) {
      for ($m=0; $m<$res->field_count; $m++) {
           if ($m==0){ 
           $id=0;
           $id=$data[$m];
       echo $id;
           }else if ($m==1){ 
             $fix=0;
             $fix=$data[$m];


             $fix = utf8_decode($fix);
             $fixx =str_replace("?"," ",$fix);

        echo $fixx;

        ////I echoed the data to the screen because I like to see something as I execute it :)
            }
            }
         $insert= "UPDATE Table SET broke_column='".$fixx."'  where inx='".$id."'";
          $insresult= $db->query($insert);
      echo"<br>";
        }

        ?>        

mã trên sửa chữa bảng của tôi. nhưng tôi khuyên bạn nên bình luận về các tuyên bố cập nhật để bạn có thể xem trước liệu nó có khắc phục được sự cố không.
drtechno

0

Vì mục đích toàn cầu.

Thay vì chuyển đổi, mã hóa, giải mã từng văn bản, tôi thích để chúng như vậy và thay vào đó thay đổi cài đặt php của máy chủ. Vì thế,

  1. Hãy để những viên kim cương

  2. Từ trình duyệt, trên menu dạng xem, hãy chọn "mã hóa văn bản" và tìm mã mà bạn có thể nhìn thấy chính xác văn bản của mình.

  3. Chỉnh sửa php.ini của bạn và thêm:

    default_charset = "ISO-8859-1"

hoặc thay vì ISO-8859 phù hợp với mã hóa văn bản của bạn.


0

Khi bạn trích xuất dữ liệu từ bất kỳ đâu, bạn nên sử dụng các hàm có tiền tố md_FUNC_NAME .

Có cùng một vấn đề nó đã giúp tôi ra ngoài.

Hoặc bạn có thể tìm mã của biểu tượng này và sử dụng regexp để xóa các biểu tượng này.


-2

Truy cập phpmyadmin của bạn và chọn cơ sở dữ liệu của bạn và chỉ cần tăng độ dài / giá trị của trường của bảng đó lên 500 hoặc 1000, nó sẽ giải quyết được vấn đề của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.