물음표와 함께 작은 검은 색 다이아몬드를 보여주는 PHP 출력


81

데이터베이스 소스에서 가져 오는 PHP 프로그램을 작성 중입니다. 일부 varchar에는 물음표가있는 검은 색 다이아몬드로 표시되는 따옴표가 있습니다 ( , REPLACEMENT CHARACTER , Microsoft Word 텍스트에서 가정).

PHP를 사용하여 이러한 문자를 제거하려면 어떻게해야합니까?


1
그들을 벗기지 말고 시간을 정하십시오. stackoverflow.com/questions/38363566/의
Rick James

답변:


74

해당 문자 ( U + FFFD "REPLACEMENT CHARACTER")가 표시되면 일반적으로 텍스트 자체가 단일 바이트 인코딩 형식으로 인코딩되지만 유니 코드 인코딩 (UTF8 또는 UTF16) 중 하나로 해석된다는 의미입니다.

만약 그것이 다른 방법이라면 (보통) 다음과 같이 보일 것입니다 : ä.

아마도 원래 인코딩은 Latin-1이라고도하는 ISO-8859-1 일 것입니다. 스크립트를 변경하지 않고도 확인할 수 있습니다. 브라우저는 다른 인코딩으로 페이지를 다시 해석 할 수있는 옵션을 제공합니다. Firefox에서는 "보기"-> "문자 인코딩"을 사용합니다.

브라우저가 올바른 인코딩을 사용하도록하려면 다음과 같은 HTTP 헤더를 추가하십시오.

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

또는 메타 태그에 인코딩을 넣으십시오.

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

또는 데이터베이스에서 다른 인코딩 (가급적이면 UTF-8)으로 읽거나 iconv().


지금까지 이것이 가장 가까운 솔루션입니다. 그러나 이제 메타가 있습니다. <meta http-equiv = "Content-Type"content = "text / html; charset = UTF-8"> 그리고 iconv를 사용하여 iso-8859-1에서 utf-로 변환합니다. 8, 캐릭터는 이제 0096 및 0092 존경심이 담긴 상자로 표시됩니다. 다른 생각이 있습니까?

네, 또 다른 생각이 있습니다. 숙제를 좀 해보세요 ... 아마도 잘못된 소스 인코딩을 사용했을 것입니다. 0x92 및 0x96은 windows-1252에서 "곡선 작은 따옴표"및 "대시"입니다. 그것이 옳은 것일 수 있습니까? 브라우저 트릭을 시도해 보셨습니까?

PDF2Text 클래스를 사용할 때 PHP 헤더가 문제를 해결했습니다.
James P.

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

@ j08691 : 글쎄요, 현재 콘텐츠 유형에 따라 다릅니다.

41

이것은 문자셋 문제입니다. 따라서 여러 수준에서 잘못되었을 수 있지만 데이터베이스의 문자열은 utf-8로 인코딩되어 있으며 iso-8859-1로 표시됩니다. 또는 그 반대입니다.

이 문제를 해결하는 적절한 방법은 문자 집합을 바로 잡는 것입니다. PHP를 사용하기 때문에 가장 간단한 전략은 애플리케이션 전체에서 iso-8859-1을 사용하는 것입니다. 이렇게하려면 다음을 확인해야합니다.

  • 모든 PHP 소스 파일은 iso-8859-1로 저장됩니다 (cp-1252와 혼동하지 마십시오).
  • 웹 서버는 다음을 사용하여 파일을 제공하도록 구성됩니다. charset=iso-8859-1
  • 또는을 사용하여 PHP 문서 내에서 웹 서버 설정을 재정의 할 수 있습니다 header.
  • 또한 동일한 내용을 지정하는 메타 태그를 HTML에 삽입 할 있지만 반드시 필요한 것은 아닙니다.
  • 당신은 할 수있다 또한 지정 accept-charset온 속성 <form>요소를.
  • 데이터베이스 테이블은 latin1로 인코딩하여 정의됩니다.
  • PHP와 데이터베이스 간의 데이터베이스 연결은 latin1로 설정됩니다.

데이터베이스에 이미 데이터가있는 경우 데이터가 이미 엉망이되었을 가능성이 있습니다. 아직 생산 단계에 있지 않은 경우 모두 지우고 다시 시작하십시오. 그렇지 않으면 데이터 정리를 수행해야합니다.

메타 태그에 대한 참고 사항 : 모두가 그것이 무엇인지 오해하기 때문입니다.

웹 서버가 파일 (HTML 문서)을 제공 할 때 브라우저에 직접 표시되지 않는 일부 정보를 보냅니다. 이를 HTTP 헤더라고합니다. 이러한 헤더 중 하나 Content-Type는 파일의 MIME 유형 (예 :)과 text/html인코딩 (일명 charset) 을 지정 하는 헤더 입니다. 대부분의 웹 서버는 정보 Content-Type와 함께 헤더를 보내지 만 charset선택 사항입니다. 존재하지 않는 경우 브라우저는 대신 http-equiv="Content-Type". 메타 태그는 웹 서버가 헤더를 보내지 않는 경우 에만 해석 된다는 것을 인식하는 것이 중요합니다 . 실제로 이것은 페이지가 디스크에 저장되고 거기에서 열리는 경우에만 사용된다는 것을 의미합니다.

이 페이지 에는 이러한 것들에 대한 아주 좋은 설명이 있습니다.


37

나는 또한이 문제에 직면했다. 한편 나는 세 가지 경우에 부딪 혔습니다.

  1. substr ()

    substr()UTF8 문자를 자르는 UTF8 문자열을 사용 하고 있었기 때문에 잘린 문자가 올바르게 표시되지 않았습니다. mb_substr($utfstring, 0, 10, 'utf-8');대신 사용하십시오 . 크레딧

  2. htmlspecialchars ()

    또 다른 문제는 htmlspecialchars()UTF8 문자열 에서 사용 하는 것입니다. 해결 방법은 다음을 사용하는 것입니다.htmlspecialchars($utfstring, ENT_QUOTES, 'UTF-8');

  3. preg_replace ()

    마지막으로 preg_replace()UTF에 문제가 발생할 수 있음을 알았습니다 . $string = preg_replace('/[^A-Za-z0-9ÄäÜüÖöß]/', ' ', $string);예를 들어 코드 는 UTF 문자열 "F (×) = 2 × -3"을 "F 2 "로 변환했습니다. 수정은 mb_ereg_replace()대신 사용하는 것입니다.

이 추가 정보가 이러한 문제를 해결하는 데 도움이되기를 바랍니다.


2
그것이 바로 제가 직면 한 문제였습니다. mb 문자열 함수에 대해 몰랐습니다.
Ren

1
strtolower기능 에도 발생했습니다 . 에 관련된 모든 기능 PHP 매뉴얼
micaball

13

이전 답변에서 언급했듯이 텍스트가 iso-8859-1인코딩 또는 기타 형식으로 데이터베이스에 작성 되었기 때문에 발생 합니다.

따라서 utf8출력 하기 전에 데이터를로 변환하기 만하면 됩니다.

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

11

MYSQL 연결이 UTF-8 (또는 사용중인 항목에 따라 latin1)으로 설정되어 있는지 확인하려면 다음을 수행 할 수 있습니다.

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

또는 이것을 사용하여 사용중인 문자 집합을 확인하십시오.

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

더 많은 정보 : http://php.net/manual/en/function.mysql-set-charset.php


이것은 매우 유용했고 원격 MySQL 데이터베이스에서 오는 데이터의 따옴표 인코딩 문제를 해결했습니다. 감사합니다!
tribulant

@ptwiggerl 이것은 많은 도움이되었습니다.
unixmiah

웹 사이트를 다른 서버로 마이그레이션했는데 mysql_set_charset ( 'utf8', $ con); 해결했습니다!
Rafael Moni

5

문제에 대한 설명에 따르면 데이터베이스의 데이터는 거의 확실하게 Windows-1252 로 인코딩되고 페이지는 거의 확실히 ISO-8859-1 로 제공됩니다 . 이 두 문자 집합은 Windows-1252에 왼쪽 및 오른쪽 둥근 따옴표를 포함하여 ISO-8859-1에없는 16 개의 추가 문자가 있다는 점을 제외하면 동일합니다.

내 분석이 정확하다고 가정 할 때 가장 간단한 해결책은 페이지를 Windows-1252로 제공하는 것입니다. ISO-8859-1에있는 모든 문자가 Windows-1252에도 있기 때문에 작동합니다. PHP에서는 다음과 같이 인코딩을 변경할 수 있습니다.

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

그러나 HTML 파일과 데이터베이스 내용에서 사용중인 문자 인코딩을 실제로 확인하고 일관성을 유지하거나 불가능한 경우 올바르게 변환해야합니다.


이 제안의 문제점은이 시점에서 데이터가 서로 다른 문자 세트의 혼합 일 가능성이 높다는 것입니다. 무엇이 잘못되었는지 정확히 모르면 여기저기서 임의의 수정 사항을 던지면 더 복잡해집니다.
troelskn

나는 동의한다. 나는이 솔루션이 당신이하는 일을 아는 것을 대체 할 수 없다는 것을 반영하기 위해 내 게시물을 다소 편집했습니다. 그러나 대부분의 개발자가이 문제를 이해할 수 없거나 신경 쓰지 않는다는 결론에 도달했습니다. 내가 일하는 곳에서 적어도 한 달에 한 번 떠오르는 것 같습니다.
Daniel Cassidy

그것은 나의 관찰이기도합니다. 내가 아끼는 것은 뿌린대로 거둔다. 하지만 당신 말이 맞을 것입니다. 그의 데이터가 실제로 cp-1252 일 가능성이 있습니다. 적어도 일부는 그렇습니다.
troelskn

나는 같은 문제에 대한 많은 해결책을 시도했습니다. 이것은 최소한의 노력으로 즉시 효과적이었습니다
sixstring

4

이 작업을 수행하여 문자열에서 이러한 문자를 제거하기로 결정했습니다.

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

1
이것은 굉장합니다, 그것은 나를 위해 일했고 utf8_encode를 시도했고 ut8_decode도 작동하지 않았습니다. 하지만이 솔루션은 제 경우에는 효과가있었습니다. 감사합니다.
sanjeev shetty

4

이 함수를 변수에 추가하십시오. utf8_encode ($ your variable);


이 답변에 대해 자세히 설명하십시오.
ppovoski

1
이것은 당신이 특수 문자 반환 당신에게 캐릭터의 UTF8 표준 제거 할 수있는 기능입니다 google.com/...을
rk_programmer

이것은 올바르게 표시되지 않은 분수에서 작동했습니다.
Rog

제 생각에 이것들은 받아 들여진 대답이어야합니다. 이것은 나를 위해 일한 유일한 방법이며 모든 것을 시도했습니다.
quantme

4

이 코드를 페이지 맨 처음부터 붙여 넣기 만하면됩니다.

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

코드의 기능에 대한 간략한 설명을 포함하십시오.
CT Hall

1
이 PHP 코드는 "ISO-8859-1"의 문자 세트를 허용하고이 문자 세트에서이 기호는 문자로 표시됩니다.
Harshil Kaneria



1

이는 유니 코드 또는 기타 문자 집합 불일치로 인해 발생할 수 있습니다. 브라우저에서 문자 집합을 변경해보십시오. 설정에서 텍스트가 정상적으로 보입니다. 그런 다음 데이터베이스 내용을 표시하는 데 사용하는 문자 집합으로 변환하는 방법에 대한 질문입니다. (실제로 출력에 utf-8 charset 문을 추가 할 수 있습니다.)


1

테이블을 수정 한 후 결국 내가했던 일은 백업하고 설정을 utf-8로 다시 변경 한 다음 덤프 파일을 변경하여 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci가 내 문자 집합 항목이되도록했습니다.

이제 데이터베이스와 브라우저가 utf8이기 때문에 더 이상 문자 집합 문제가 없습니다.

그 원인을 알아 냈습니다. DB에 대한 웹 페이지 + 브라우저 효과였습니다. Linux (ubuntu + firefox) 인 터미널에서는 탭이 설정된 latin1로 데이터베이스를 인코딩했습니다. 그러나 Windows 10 + edge 터미널에서는 항목이 utf8로 강제 코딩되었습니다. 또한 Windows 10에 latin1에 머무르는 데 문제가 있음을 알았으므로 바람에 따라 구부리고 모두 utf8로 변환하기로 결정했습니다.

Win 10 터미널을 사용하기 시작했기 때문에 Windows 10 문제라고 생각했습니다. 다시 한 번 Microsoft 버그로 인해 문제가 발생합니다. Windows 10의 브라우저가 latin1 문자 집합을 표시하기 때문에 양식에서 인코딩이 변경되는 이유를 모르겠지만 utf8로 인코딩되어 데이터 이상이 발생합니다. 하지만 linux + firefox에서는 그렇게하지 않습니다.


1

이것은 내 경우에 작동했습니다.

$text = utf8_decode($text)

검은 색 다이아몬드 문자를 물음표로 바꿔서 다음을 수행 할 수 있습니다.

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

1
[정보 경고 $text = 섹션이 문자열 내의 모든 물음표가 변경됩니다,뿐만 아니라 다이아몬드
treyBake

1

헤더 앞에이 줄을 추가하기 만하면됩니다.

정확한 .doc/docx파일 형식 이 검색됩니다.

 if(ini_get('zlib.output_compression'))

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

0

브라우저에서 설정 한 caracter를 변경할 수도 있습니다. 디버그 이유로.


0

데이터베이스와 HTML 모두에서 동일한 문자 세트 (여기에 제안 된대로)를 사용하는 것이 저에게 효과적이지 않았습니다 ... 따라서 코드가 HTML로 생성된다는 것을 기억하면서 &quot;(HTML 코드) 또는 &#34;(ISO Latin-1 코드) 따옴표가 사용 된 데이터베이스 텍스트에서. 이것은 나에게 인용 부호를 제공하면서 문제를 해결했습니다. 이 솔루션 이전에는 일부 인용 부호와 아포스트로피 만 올바르게 표시되지 않았고 다른 일부는 올바르게 표시되지 않았지만 특수 코드는 모든 경우에 작동했습니다.


0

phpmyadmin에서 데이터 정렬을 변경 한 후 "인코딩 감지"코드를 실행했는데 이제 Latin_1로 표시됩니다.

하지만 여기에 내 응용 프로그램에서 다른 데이터 이상을 발견하고 그것을 수정하는 방법이 있습니다.

방금 혼합 인코딩 (일부 줄에 다이아몬드 물음표가 있고 모두 동일한 열에 있음)이있는 테이블을 가져 왔으므로 여기에 수정 코드가 있습니다. 정의되지 않은 자리 표시자를 사용하고 "다이아몬드 물음표"대신 일반 물음표를 할당하는 utf8_decode 프로세스를 사용한 다음 str_replace를 사용하여 물음표를 따옴표 사이의 공백으로 대체했습니다. 여기에 [코드]

    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>";
        }

        ?>        

위의 코드는 내 테이블을 수정합니다. 그러나 문제를 해결할 것인지 먼저 확인할 수 있도록 업데이트 설명에 주석을 달 것을 권장합니다.
drtechno

0

글로벌 목적을 위해.

각 텍스트를 변환, 코드화, 해독하는 대신에 그대로두고 서버 PHP 설정을 변경하는 것을 선호합니다. 그래서,

  1. 다이아몬드 보자

  2. 브라우저의보기 메뉴에서 "텍스트 인코딩"을 선택하고 텍스트를 올바르게 볼 수있는 인코딩을 찾으십시오.

  3. php.ini를 편집하고 다음을 추가하십시오.

    default_charset = "ISO-8859-1"

또는 텍스트 인코딩에 맞는 ISO-8859 대신.


0

어디에서나 데이터를 추출 할 때 접두사가있는 함수를 사용해야합니다 md_FUNC_NAME.

그것은 나를 도왔던 것과 같은 문제가 있었다.

또는이 기호의 코드를 찾고 regexp를 사용하여 이러한 기호를 삭제할 수 있습니다.


-2

phpmyadmin으로 이동하여 데이터베이스를 선택하고 해당 테이블 필드의 길이 / 값을 500 또는 1000으로 늘리면 문제가 해결됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.