PHP: 원래 문자 집합을 모르는 상태에서 문자열을 UTF-8로 변환하거나 최소한 시도해 보십시오.
저는 전 세계 고객을 상대하는 어플리케이션을 가지고 있는데, 당연히 제 데이터베이스로 들어가는 모든 것을 UTF-8로 인코딩하고 싶습니다.
큰 문제는 입니다. 텍스트 사용할 경우)에 수 . 텍스트박스를 사용할 수도 있습니다.<form accept-charset="utf-8">사용자에게 실제로 폼이 송신되어 있는 경우에만 유효합니다).또는 업로드된 텍스트파일에서 취득한 것이므로 입력은 제가 제어할 수 없습니다.
필요한 것은 데이터베이스로 전송되는 데이터를 가능한 한 UTF-8로 인코딩할 수 있는 기능 또는 클래스입니다.iconv(mb_detect_encoding($text), "UTF-8", $text);아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.여러가지 시도를 해봤어 =/
파일 업로드에서는 최종 사용자에게 사용하는 인코딩을 지정하고 출력의 프리뷰를 표시하도록 지시하는 것은 마음에 듭니다만, 이것은 악의적인 해커에 대해서는 도움이 되지 않습니다(실제로 그들의 생활이 조금 더 쉬워질 수도 있습니다).
Stack Overflow에 관한 다른 질문은 읽었지만, "RSS 피드를 해석해야 한다" 또는 "웹 사이트에서 데이터를 긁어모으는다"와 같은 미묘한 차이가 있는 것 같습니다.
하지만 적어도 좋은 시도를 할 수 있는 무언가가 있을 거야!
당신이 요구하는 것은 매우 어렵습니다.가능하면 사용자가 인코딩을 지정하도록 하는 것이 가장 좋습니다.공격을 막는 것이 그렇게 쉽거나 어렵지는 않을 것입니다.
단, 다음과 같이 시도해 볼 수 있습니다.
iconv(mb_detect_encoding($text, mb_detect_order(), true), "UTF-8", $text);
이 값을 strict로 설정하면 더 나은 결과를 얻을 수 있습니다.
조국 러시아에는 4개의 인기 있는 인코딩이 있기 때문에, 당신의 질문이 매우 요구되고 있습니다.
코드 페이지가 교차하기 때문에 기호 문자 코드만으로 인코딩을 감지할 수 없습니다.다른 언어의 코드 페이지에는 완전한 교차점이 있는 것도 있습니다.그래서 우리는 다른 접근이 필요하다.
알 수 없는 인코딩으로 작업하는 유일한 방법은 확률로 작업하는 것입니다.그래서 '이 텍스트의 부호화란 무엇인가?'라는 질문에 답하는 것이 아니라 '이 텍스트의 부호화 가능성이 가장 높은 것은 무엇인가?'라는 것을 이해하려고 합니다.
여기 러시아의 유명한 기술 블로그에 있는 한 남자가 이 방법을 발명했습니다.
지원하는 모든 인코딩에서 문자 코드의 확률 범위를 구성합니다.언어의 큰 텍스트를 사용하여 만들 수 있습니다(예: 일부 픽션, 영어의 경우 셰익스피어, 러시아어의 경우 톨스토이 사용, LOL).다음과 같은 결과를 얻을 수 있습니다.
encoding_1:
190 => 0.095249209893009,
222 => 0.095249209893009,
...
encoding_2:
239 => 0.095249209893009,
207 => 0.095249209893009,
...
encoding_N:
charcode => probabilty
그런 다음 알 수 없는 인코딩의 텍스트를 가져와 "확률 사전"의 모든 인코딩에 대해 알 수 없는 인코딩 텍스트의 모든 기호 빈도를 검색합니다.기호의 확률을 합산합니다.등급이 큰 인코딩이 승자가 될 수 있습니다.글자가 클수록 더 좋은 결과가 나온다.
Btw, mb_detect_encoding은 확실히 동작하지 않습니다.네, 전혀 없어요."ext/mbstring/libmbfl/mbfl/mbfl_ident.c"에서 mb_detect_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);
결과는 둘 다 똑같습니다.
문자열의 문자 세트를 완전히 정확하게 식별할 수 있는 방법은 없습니다.
문자 집합을 추측하는 방법은 여러 가지가 있습니다.이러한 방법 중 하나이며, 현재 PHP에서 가장 좋은 방법은 mb_detect_encoding입니다.문자열을 스캔하여 특정 문자 집합에 고유한 항목이 있는지 찾습니다.문자열에 따라 이와 같이 구별 가능한 항목이 없을 수 있습니다.
ISO-8859-1 문자 집합과 ISO-8859-15 문자 집합을 비교합니다.
몇 개의 다른 문자밖에 없고, 설상가상으로 같은 바이트로 표시됩니다.바이트 0xA4가 스트링 내에서 , 또는 €를 나타내는지 여부를 부호화하지 않고 스트링을 지정받으면 검출할 수 없기 때문에 그 문자 세트를 정확하게 알 수 없습니다.
(주의: 인적 요인 또는 보다 고도의 스캔 기술(Oroboros102의 제안 등)을 추가하여 주변 컨텍스트에 따라 문자가 ) 또는 €이어야 하는지 여부를 판단할 수 있습니다.단, 너무 먼 것 같습니다).
예를 들어 UTF-8과 ISO-8859-1 사이에는 더 많은 구별 가능한 차이점이 있기 때문에 확실치 않을 때 알아보는 것이 좋습니다.그러나 정확하다고 믿을 수 있는 것은 결코 아닙니다.
재미있는 읽을거리:문자열의 문자 집합/인코딩을 확인하려면 어떻게 해야 합니까?
그러나 올바른 문자 집합을 보장하는 다른 방법이 있습니다.폼에 관해서는 가능한 한 UTF-8을 적용하도록 한다(스노우맨을 체크하여 모든 브라우저에서 UTF-8이 제출되었는지 확인한다: Rails and Snowmen).
이 작업을 완료하면 적어도 양식을 통해 제출된 모든 텍스트가 utf_8임을 확인할 수 있습니다.업로드된 파일에 대해서는 (가능한 경우 서버에서) exec()과 같이 UNIX 'file -i' 명령을 실행하여 (문서의 BOM을 사용하여) 검색을 지원합니다.
데이터 스크랩에 관해서는 보통 문자 세트를 지정하는HTTP 헤더를 읽을 수 있습니다.XML 파일을 해석할 때 XML 메타데이터에 문자 집합 정의가 포함되어 있는지 확인합니다.
문자 집합을 자동으로 추측하기보다는 가능한 경우 특정 문자 집합을 직접 확인하거나, 해당 문자 집합을 가져온 소스(해당하는 경우)에서 정의를 가져와야 합니다.
여기 정말 좋은 답변과 당신의 질문에 대한 답변 시도가 있습니다.저는 부호화 마스터는 아니지만 UTF-8 스택을 데이터베이스까지 전송하고 싶은 마음은 이해합니다.MySQL을 사용하고 있습니다.utf8mb4테이블, 필드 및 연결에 대한 인코딩입니다.
"HTML 폼이나 이메일 등록 링크에서 데이터를 가져올 때 UTF-8을 처리할 수 있는 검사기, 검증기, 비즈니스 로직 및 준비된 스테이트먼트를 원합니다."로 요약할 수 있습니다.그래서 저는 간단한 방법으로 이 아이디어를 시작했습니다.
: " " " "
$encodings = ['UTF-8', 'ISO-8859-1', 'ASCII'];할 수 는, 「」를 해 주세요.
throw new RuntimeException이 '하다'인
UTF-8계속하세요.않으면, 「 」의 경우.
ISO-8859-1★★★★★★★★★★★★★★★★★」ASCIIa. UTF-8로의 변환 시도(대기, 미완료)
b. 변환된 값의 부호화를 검출한다.
. c인 .
UTF-8계속하세요.d. 렇지 d d d d
throw new RuntimeException
★★★★★★★★★★★★★★★★★★★★★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하면 됩니다.Encoder인 예를 Sanitizer그러나 나의 접근법의 가장 큰 문제는 더 많은 지식이 없으면 내가 원하지 않는 인코딩 유형을 거부한다는 것이다(그리고 나는 PHP mb_* 함수에 의존하고 있다).더 많은 연구가 없다면, 나는 그것이 일부 사람들에게 피해를 주는 것인지 아닌지 알 수 없다.그래서 좀 더 배워야겠어요.나는 이 기사를 발견했다.
모든 프로그래머가 텍스트로 작업하기 위해 인코딩과 문자 집합에 대해 반드시 알아야 하는 것
암호화된 (「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」를 사용합니다.OpenSSL ★★★★★★★★★★★★★★★★★」mcrypt? 디코딩에 방해가 될 수 있습니까?Windows-1252는 어떻습니까?보안에 대한 영향은 어떻습니까?의 사용utf8_decode() ★★★★★★★★★★★★★★★★★」utf8_encode()Sanitizer::isUTF8심스럽럽다다
PHP mb_* 입니다.는 조사하는데 을 들이지 않았다.iconv보다 더 잘
가장 큰 문제는 문자열의 소스가 어떤 인코딩이 될지 모른다는 것입니다.텍스트 박스에서 사용할 수도 있고(사용자가 실제로 양식을 제출한 경우에만 사용할 수도 있음), 업로드된 텍스트 파일에서 사용할 수도 있기 때문에 입력을 제어할 수 없습니다.
문제될 게 없는 것 같아요.애플리케이션은 입력의 소스를 인식합니다.폼의 경우 UTF-8 인코딩을 사용합니다.됐다.제공된 데이터가 올바르게 인코딩되어 있는지(검증)만 확인합니다.모든 데이터베이스가 UTF-8을 지원하는 것은 아닙니다.
파일일 경우 UTF-8로 인코딩된 파일을 데이터베이스에 저장하지 않고 바이너리 형식으로 저장합니다.파일을 다시 출력할 때는 바이너리 출력도 사용합니다.그러면 완전히 투과적입니다.
바이너리이기 때문에 사용자가 파일을 다운로드한 후에라도 인코딩을 알 수 있다는 것은 좋은 생각입니다.
그래서 나는 당신이 당신의 질문에 대해 특별한 문제를 제기하지 않는다는 것을 인정해야 한다.
질문에 대한 답변은 충분히 된 것 같습니다만, 사례를 단순화할 수 있는 방법이 있습니다.
MySQL에서 문자열 데이터를 반환하려고 할 때도 비슷한 문제가 있었습니다.데이터베이스와 PHP 모두 UTF-8로 포맷된 문자열을 반환하도록 설정했습니다.내가 오류를 얻은 유일한 방법은 실제로 데이터베이스에서 그것들을 반환하는 것이었다.
마지막으로 웹을 통해 항해하면서 정말 쉽게 대처할 수 있는 방법을 찾았습니다.
MySQL에 있는 모든 종류의 문자열 데이터를 다른 형식과 조합으로 저장할 수 있도록 하려면 php 연결 파일에서 다음과 같이 조합 설정을 UTF-8로 하면 됩니다.
$connection = new mysqli($server, $user, $pass, $db);
$connection->set_charset("utf8");
즉, 우선 데이터를 임의의 형식이나 조합으로 저장하고 PHP 파일로 반환할 때만 변환합니다.
'콘솔로 가져가실 의향이 있으시다면'enca. 다소 단순한 것과는 달리mb_detect_encoding, "파싱, 통계 분석, 추측 및 블랙 매직의 혼합"을 사용하여 인코딩을 결정합니다(man 페이지 참조).그러나 이러한 국가별 인코딩을 탐지하려면 일반적으로 입력 파일의 언어를 전달해야 합니다.(단,mb_detect_encoding는 기본적으로 동일한 요건을 가지고 있습니다.이는 부호화가 검출되기 위해서는 통과된 부호화 목록에 "적절한 장소에" 표시되어야 하기 때문입니다.)
enca여기도 올라왔어요스크립트를 통해 Unix에서 파일 인코딩을 찾는 방법
밖에 도서관이 몇 군데 있어요.onnov/detect-flash는 유망해 보입니다.mb_detect_encoding보다 더 잘 동작한다고 주장합니다.
알 수 없는 문자 부호화의 문자열을 UTF-8로 변환하는 사용 예:
use Onnov\DetectEncoding\EncodingDetector;
$detector->iconvXtoEncoding('Проверяемый текст')
부호화를 검출하는 방법:
$encoding = $detector->getEncoding('Проверяемый текст');
메트릭 세트를 설정하여 어떤 인코딩이 사용되는지 추측할 수 있습니다.이 경우에도 완벽하지는 않지만 mb_detect_encoding()에서 일부 누락이 발생할 수 있습니다.
UTF-8은 널리 사용되고 있기 때문에 디폴트로 상정할 수 있습니다.디폴트가 아닌 경우는, 부호화를 추측해 변환해 보겠습니다.코드는 다음과 같습니다.
function make_utf8(string $string)
{
// Test it and see if it is UTF-8 or not
$utf8 = \mb_detect_encoding($string, ["UTF-8"], true);
if ($utf8 !== false) {
return $string;
}
// From now on, it is a safe assumption that $string is NOT UTF-8-encoded
// The detection strictness (i.e. third parameter) is up to you
// You may set it to false to return the closest matching encoding
$encoding = \mb_detect_encoding($string, mb_detect_order(), true);
if ($encoding === false) {
throw new \RuntimeException("String encoding cannot be detected");
}
return \mb_convert_encoding($string, "UTF-8", $encoding);
}
심플하고 안전하며 고속.
MySQL 데이터베이스에서 텍스트를 검색할 경우 데이터베이스 연결 후 이 텍스트를 추가할 수 있습니다.
mysqli_set_charset($con, "utf8");
언급URL : https://stackoverflow.com/questions/7979567/php-convert-any-string-to-utf-8-without-knowing-the-original-character-set-or
'programing' 카테고리의 다른 글
| 많은 인수를 메서드에 전달하기 위한 베스트 프랙티스? (0) | 2022.10.22 |
|---|---|
| MySQL Workbench - 테이블 데이터 가져오기 마법사(모든 날짜/시간 개체를 0000-00 00:00:00:00로 기록) (0) | 2022.10.22 |
| .jar 파일의 클래스를 사용하는 방법 (0) | 2022.10.22 |
| __asm____volatile__는 C에서 무엇을 합니까? (0) | 2022.10.22 |
| 어레이에 여러 요소가 있는지 확인하는 더 좋은 방법은 무엇입니까? (0) | 2022.10.21 |
