복붙노트

PHP : 원래의 문자 집합을 모른 채 모든 문자열을 UTF-8로 변환하거나 적어도 시도하십시오.

PHP

PHP : 원래의 문자 집합을 모른 채 모든 문자열을 UTF-8로 변환하거나 적어도 시도하십시오.

나는 전세계의 고객들과 거래하는 응용 프로그램을 가지고 있으며 당연히 모든 데이터베이스가 UTF-8로 인코딩되기를 원합니다.

필자가 생각하기에 가장 중요한 문제는 문자열의 소스를 인코딩하는 것이 무엇인지 알지 못한다는 것입니다. 텍스트 상자 (

사용)는 사용자가 실제로 양식을 제출 한 경우) 또는 업로드 된 텍스트 파일 일 수 있으므로 입력에 대한 제어권이 없습니다.

내가 필요로하는 것은 가능한 한 UTF-8로 인코딩 된 데이터를 데이터베이스에 저장하는 함수 또는 클래스입니다. 나는 iconv (mb_detect_encoding ($ text), "UTF-8", $ text)를 시도했다. 그러나 그것은 문제가 있습니다 (입력이 'fiancée'이면 'fianc'을 반환합니다). 나는 많은 것을 시도했다 = /

파일 업로드의 경우, 최종 사용자에게 그들이 사용하는 인코딩을 지정하고 결과물을 미리보기로 표시하도록 요청하는 아이디어가 마음에 들지만, 이는 해커의 불쾌감을 방지하는 데는 도움이되지 않습니다. 사실, 좀 더 쉽게).

주제에 대한 다른 SO 질문을 읽었지만 "나는 RSS 피드를 구문 분석해야합니다"또는 "웹 사이트에서 데이터를 긁어 낼 필요가 있습니다"와 같은 미묘한 차이가있는 것 같습니다 (실제로는 "할 수 없습니다").

그러나 적어도 좋은 시도가있는 무언가가 있어야합니다!

해결법

  1. ==============================

    1.당신이 요구하는 것은 극히 어렵습니다. 가능한 경우 사용자가 인코딩을 지정하도록하는 것이 가장 좋습니다. 공격을 예방하는 것이 그렇게 쉽고 어렵지 않아야합니다.

    당신이 요구하는 것은 극히 어렵습니다. 가능한 경우 사용자가 인코딩을 지정하도록하는 것이 가장 좋습니다. 공격을 예방하는 것이 그렇게 쉽고 어렵지 않아야합니다.

    그러나 다음과 같이 시도해 볼 수 있습니다.

    iconv(mb_detect_encoding($text, mb_detect_order(), true), "UTF-8", $text);
    

    엄격하게 설정하면 더 나은 결과를 얻을 수 있습니다.

  2. ==============================

    2.조국 러시아에서는 4 개의 인기있는 인코딩이 있으므로 여기에 귀하의 질문에 큰 요구가 있습니다.

    조국 러시아에서는 4 개의 인기있는 인코딩이 있으므로 여기에 귀하의 질문에 큰 요구가 있습니다.

    코드 페이지가 교차하기 때문에 기호의 char 코드에 의해서만 인코딩을 감지 할 수 없습니다. 다른 언어로 된 일부 코드 페이지는 완전한 교차점을가집니다. 그래서 우리는 또 다른 접근법이 필요합니다.

    알 수없는 인코딩으로 작업하는 유일한 방법은 확률로 작업하는 것입니다. 그래서 우리는 "이 텍스트의 인코딩은 무엇입니까?"라는 질문에 답하기를 원하지 않습니다. "우리는이 텍스트의 인코딩 가능성이 가장 높습니다"라고 이해하려고합니다.

    인기있는 러시아 기술 블로그에있는 한 사람이이 접근 방법을 고안했습니다.

    지원하려는 모든 인코딩에서 char 코드의 확률 범위를 작성하십시오. 당신은 당신의 언어로 몇 가지 큰 텍스트를 사용하여 그것을 구축 할 수 있습니다 (예를 들어, 어떤 픽션, 영어의 경우 셰익스피어, 러시아어의 경우 톨스토이, 롤). 당신은 다음과 같이 스턴을 얻을 것입니다 :

        encoding_1:
        190 => 0.095249209893009,
        222 => 0.095249209893009,
        ...
        encoding_2:
        239 => 0.095249209893009,
        207 => 0.095249209893009,
        ...
        encoding_N:
        charcode => probabilty
    

    다음 것. 알 수없는 인코딩으로 텍스트를 가져오고 "확률 사전"의 모든 인코딩에 대해 알 수없는 인코딩 된 텍스트의 모든 심볼의 빈도를 검색합니다. 심볼의 합계 확률. 더 큰 등급의 인코딩이 승자 일 가능성이 높습니다. 더 큰 텍스트에 대한 더 나은 결과.

    관심이 있으시면 기꺼이 도와 드리겠습니다. 두 개의 문자 코드 확률 목록을 작성하여 정확도를 크게 높일 수 있습니다.

    Btw. mb_detect_encoding certanly 작동하지 않습니다. 네. "ext / mbstring / libmbfl / mbfl / mbfl_ident.c"에있는 mb_detect_encoding 소스 코드를보십시오.

  3. ==============================

    3.이것을 시도해 보았지만 mb_convert_encoding 함수를 사용하지 않는 이유는 무엇입니까? 제공된 텍스트의 문자 집합을 자동 감지하려고 시도하거나 목록에 전달할 수 있습니다.

    이것을 시도해 보았지만 mb_convert_encoding 함수를 사용하지 않는 이유는 무엇입니까? 제공된 텍스트의 문자 집합을 자동 감지하려고 시도하거나 목록에 전달할 수 있습니다.

    또한, 나는 실행하려고 :

    $text = "fiancée";
    echo mb_convert_encoding($text, "UTF-8");
    echo "<br/><br/>";
    echo iconv(mb_detect_encoding($text), "UTF-8", $text);
    

    결과는 둘 다 동일합니다. 텍스트가 '약혼자'로 잘린 것을 어떻게 알 수 있습니까? 그것은 DB 또는 브라우저에 있습니까?

  4. ==============================

    4.완전히 정확한 문자열의 문자 세트를 식별 할 수있는 방법은 없습니다. charset을 추측 해 볼 수있는 방법이 있습니다. PHP에서 가장 좋은 방법 중 하나는 mb_detect_encoding ()입니다. 이렇게하면 문자열을 스캔하여 특정 문자 집합에 고유 한 항목이 있는지 찾습니다. 문자열에 따라 구별 할 수없는 경우가 있습니다.

    완전히 정확한 문자열의 문자 세트를 식별 할 수있는 방법은 없습니다. charset을 추측 해 볼 수있는 방법이 있습니다. PHP에서 가장 좋은 방법 중 하나는 mb_detect_encoding ()입니다. 이렇게하면 문자열을 스캔하여 특정 문자 집합에 고유 한 항목이 있는지 찾습니다. 문자열에 따라 구별 할 수없는 경우가 있습니다.

    ISO-8859-1 문자 세트 대 ISO-8859-15 (http://en.wikipedia.org/wiki/ISO/IEC_8859-15#Changes_from_ISO-8859-1)

    소수의 문자 만 있고, 문자를 더 나쁜 것으로 만들려면 문자가 같은 바이트로 표시됩니다. 바이트 0xA4가 문자열에서 ¤ 또는 €을 나타낼 것인지 여부를 알지 못해 문자열을 감지 할 수있는 방법이 없으므로 정확한 charset을 알 수있는 방법이 없습니다.

    (참고 : 인간의 요소를 추가하거나, Oroboros102가 제시하는 것과 같은 더욱 향상된 스캐닝 기법을 추가하여 주변의 상황을 기반으로 파악하려고 시도 할 수 있습니다. 예를 들어 브리지처럼 보이더라도 캐릭터가 ¤ 또는 €이어야합니다. 너무 멀리)

    예를 들어, UTF-8 및 ISO-8859-1을 사용하므로 확실하지 않을 때도 알아낼 가치가 있습니다.

    재미있는 읽기 : http://kore-nordmann.de/blog/php_charset_encoding_FAQ.html#how-do-i-determine-the-charset-encoding-of-a-string

    그러나 올바른 문자 집합을 보장하는 다른 방법이 있습니다. 형식과 관련하여 가능한 한 UTF-8을 시행하십시오 (눈사람을 확인하여 모든 브라우저에서 제출할 UTF-8을 확인하십시오.) : http://intertwingly.net/blog/2010/07/29/Rails-and -Snowmen) 완료되면 적어도 양식을 통해 제출 된 모든 텍스트가 utf_8인지 확인할 수 있습니다. 업로드 된 파일에 관해서는 예를 들어 unix 'file -i'명령을 실행 해보십시오. exec () (가능한 경우 서버에서)를 사용하여 탐지를 돕습니다 (문서의 BOM 사용). 데이터 스크래핑과 관련하여 일반적으로 charset을 지정하는 HTTP 헤더를 읽을 수 있습니다. XML 파일을 구문 분석 할 때 XML 메타 데이터에 charset 정의가 포함되어 있는지 확인하십시오.

    자동적으로 charset을 추측하려고 시도하기보다는 가능한 한 특정 charset을 확인하거나 감지에 의지하기 전에 (존재하는 경우) 소스에서 정의를 가져 오려고 시도해야합니다.

  5. ==============================

    5.나는 그것이 문제라고 생각하지 않는다. 응용 프로그램은 입력 소스를 알고 있습니다. 양식의 경우 UTF-8 인코딩을 사용하십시오. 그거야. 제공된 데이터가 올바르게 인코딩되었는지 확인하십시오 (유효성 검사). 모든 데이터베이스가 모든 범위에서 UTF-8을 지원하는 것은 아닙니다.

    나는 그것이 문제라고 생각하지 않는다. 응용 프로그램은 입력 소스를 알고 있습니다. 양식의 경우 UTF-8 인코딩을 사용하십시오. 그거야. 제공된 데이터가 올바르게 인코딩되었는지 확인하십시오 (유효성 검사). 모든 데이터베이스가 모든 범위에서 UTF-8을 지원하는 것은 아닙니다.

    파일 인 경우 UTF-8을 데이터베이스에 인코딩하지 않고 바이너리 형식으로 저장합니다. 파일을 다시 출력 할 때 이진 출력도 사용하면 완전히 투명합니다.

    사용자가 파일을 다운로드 한 후 어쨌든 말할 수 있으면 인코딩을 알 수 있다는 아이디어는 좋지만 바이너리이기 때문입니다.

    그래서 나는 당신이 당신의 질문으로 제기하는 특정한 이슈를 보지 못한다는 것을 인정해야합니다. 하지만 문제가 무엇인지 더 자세히 설명해 줄 수는 있습니다.

  6. ==============================

    6.어떤 인코딩이 사용되는지 추측하려고하는 일련의 메트릭을 설정할 수 있습니다. 다시 말하지만 완벽하지는 않지만 mb_detect_encoding ()에서 누락 된 부분을 잡을 수 있습니다.

    어떤 인코딩이 사용되는지 추측하려고하는 일련의 메트릭을 설정할 수 있습니다. 다시 말하지만 완벽하지는 않지만 mb_detect_encoding ()에서 누락 된 부분을 잡을 수 있습니다.

  7. ==============================

    7."콘솔에 가져가"기꺼이한다면, 나는 enca를 권하고 싶습니다. 오히려 단순한 mb_detect_encoding과 달리, "해석, 통계 분석, 추측 및 흑 마법을 혼합하여 인코딩을 결정합니다"(lol - 맨 페이지 참조). 그러나 국가 별 인코딩을 검색하려면 입력 파일의 언어를 전달해야합니다. (그러나, mb_detect_encoding은 본질적으로 동일한 요구 사항을 가지고 있습니다. 왜냐하면 인코딩은 전달 된 인코딩 목록에서 "적절한 위치에"나타나야 만 탐지 할 수 있기 때문입니다.)

    "콘솔에 가져가"기꺼이한다면, 나는 enca를 권하고 싶습니다. 오히려 단순한 mb_detect_encoding과 달리, "해석, 통계 분석, 추측 및 흑 마법을 혼합하여 인코딩을 결정합니다"(lol - 맨 페이지 참조). 그러나 국가 별 인코딩을 검색하려면 입력 파일의 언어를 전달해야합니다. (그러나, mb_detect_encoding은 본질적으로 동일한 요구 사항을 가지고 있습니다. 왜냐하면 인코딩은 전달 된 인코딩 목록에서 "적절한 위치에"나타나야 만 탐지 할 수 있기 때문입니다.)

    enca도 여기에 올랐습니다 : Unix에서 스크립트를 통해 파일의 인코딩을 찾는 방법

  8. ==============================

    8.정말 좋은 답변과 여기에 귀하의 질문에 대한 답변 시도가 있습니다. 나는 인코딩 마스터가 아니지만 데이터베이스에 순수 UTF-8 스택을 갖길 원합니다. 테이블, 필드 및 연결에 MySQL의 utf8mb4 인코딩을 사용하고 있습니다.

    정말 좋은 답변과 여기에 귀하의 질문에 대한 답변 시도가 있습니다. 나는 인코딩 마스터가 아니지만 데이터베이스에 순수 UTF-8 스택을 갖길 원합니다. 테이블, 필드 및 연결에 MySQL의 utf8mb4 인코딩을 사용하고 있습니다.

    내 상황은 "HTML 형식이나 전자 메일 등록 링크에서 데이터를 가져올 때 UTF-8을 처리하기 위해 내 살생자, 유효성 검사기, 비즈니스 논리 및 준비된 문이 필요할뿐입니다."라고 말했습니다. 그래서, 간단한 방법으로, 나는이 아이디어로 시작했습니다 :

    내 추상 클래스 Sanitizer에서

        private function isUTF8($encoding, $value)
        {
            return (($encoding === 'UTF-8') && (utf8_encode(utf8_decode($value)) === $value));
        }
    
        private function utf8tify(&$value)
        {
            $encodings = ['UTF-8', 'ISO-8859-1', 'ASCII'];
    
            mb_internal_encoding('UTF-8');
            mb_substitute_character(0xfffd); //REPLACEMENT CHARACTER
            mb_detect_order($encodings);
    
            $stringEncoding = mb_detect_encoding($value, $encodings, true);
    
            if (!$stringEncoding) {
                $value = null;
                throw new \RuntimeException("Unable to identify character encoding in sanitizer.");
            }
    
            if ($this->isUTF8($stringEncoding, $value)) {
                return;
            } else {
                $value = mb_convert_encoding($value, 'UTF-8', $stringEncoding);
                $stringEncoding = mb_detect_encoding($value, $encodings, true);
    
                if ($this->isUTF8($stringEncoding, $value)) {
                    return;
                } else {
                    $value = null;
                    throw new \RuntimeException("Unable to convert character encoding from ISO-8859-1, or ASCII, to UTF-8 in Sanitizer.");
                }
            }
    
            return;
        }
    

    하나는 내가 추상 Sanitizer 클래스에서 인코딩 문제를 분리하고 Sanitizer의 구체적인 자식 인스턴스에 Encoder 객체를 삽입해야한다는 주장을 할 수 있습니다. 그러나, 내 접근법의 가장 큰 문제점은 더 많은 지식이 없으면 원하지 않는 인코딩 유형을 거부한다는 것입니다. PHP mb_ * 함수를 사용하고 있습니다. 더 많은 연구없이, 나는 그것이 어떤 인구를 아프게하는지 아닐지 (또는 내가 중요한 정보를 잃어 버리면) 알 수 없다. 그래서, 나는 더 많은 것을 배울 필요가있다. 나는이 기사를 발견했다.

    모든 프로그래머가 텍스트 작업을위한 인코딩 및 문자 세트에 대해 절대적으로 알고 있어야하는 점

    또한 암호화 된 데이터가 내 이메일 등록 링크 (OpenSSL 또는 mcrypt 사용)에 추가되면 어떻게됩니까? 이것이 디코딩을 방해 할 수 있습니까? Windows-1252는 어떻습니까? 보안 관련 사항은 무엇입니까? Sanitizer :: isUTF8에서 utf8_decode () 및 utf8_encode ()를 사용하는 것은 의심 스럽습니다.

    사람들은 PHP mb_ * 함수의 단점을 지적했습니다. 나는 iconv에 대해 조사한 적이 없지만 mb_ * 함수보다 더 잘 작동한다면 알려주지.

  9. ==============================

    9.

    public function convertToUtf8($text) {
        if(!$this->html)
            $this->html = cURL('http://'.$this->url, array('timeout' => 15));
    
        $html = $this->html;
        preg_match('/<meta.*?charset=(|\")(.*?)("|\")/i', $html, $matches);
    
        $charset = $matches[2];
    
        if($charset)
            return mb_convert_encoding($text, 'UTF-8', $charset);
        else
            return $text;
    }
    

    cURL 기본 옵션 :

    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    

    나는 이런 것을 시도했다. 그것은 나를 도왔다. meta charset 정보에서 발견되면 변환하지 않으면 아무것도 수행하지 않습니다.

  10. ==============================

    10.귀하의 질문에 대한 답변이 많은 것 같지만 귀하의 사례를 단순화 할 수있는 방법이 있습니다.

    귀하의 질문에 대한 답변이 많은 것 같지만 귀하의 사례를 단순화 할 수있는 방법이 있습니다.

    비슷한 문제가 mysql에서 문자열 데이터를 반환하려고했는데 심지어 데이터베이스와 PHP를 모두 utf-8로 포맷 된 문자열을 반환하도록 구성했습니다. 오류가 발생하는 유일한 방법은 실제로 그들을 데이터베이스에서 반환하는 것입니다.

    마지막으로 웹을 통해 항해하면 정말 쉽게 해결할 수 있습니다.

    mysql에있는 모든 형식의 문자열 데이터를 다양한 형식과 데이터 정렬로 저장할 수 있으므로 PHP 연결 파일에서 다음과 같이 데이터 정렬을 utf-8로 설정하면됩니다.

    $connection = new mysqli($server, $user, $pass, $db);
    $connection->set_charset("utf8");
    

    즉, 먼저 데이터를 모든 형식 또는 데이터 정렬로 저장하고 PHP 파일로 반환 할 때만 데이터를 변환한다는 의미입니다.

    희망이 도움이되었다!

  11. from https://stackoverflow.com/questions/7979567/php-convert-any-string-to-utf-8-without-knowing-the-original-character-set-or by cc-by-sa and MIT license