php - apache directory charset




UTF-8 끝까지 (9)

MySQL 서버가 클라이언트가 아닌 PHP (character set)를 클라이언트로 결정하기를 원한다면 (필자의 의견으로는, 필자의 의견으로는 선호), [mysqld] 아래의 my.cnf skip-character-set-client-handshake 를 추가하고 mysql 재시작하십시오.

이것은 UTF8 이외의 것을 사용하는 경우 문제를 일으킬 수 있습니다.

새 서버를 설치하고 웹 응용 프로그램에서 UTF-8을 완벽하게 지원하려고합니다. 나는 기존의 서버에서 과거에 시도해 왔으며 항상 ISO-8859-1로 돌아 가야만하는 것처럼 보입니다.

인코딩 / 문자셋을 정확히 설정해야하는 곳은 어디입니까? 나는 이것을하기 위해 아파치, MySQL, PHP를 설정해야한다는 것을 알고있다 - 따라 할 수있는 표준 체크리스트가 있는가, 아니면 불일치가 발생하는 곳에서 문제를 해결할 것인가?

이것은 MySQL 5, PHP 5 및 Apache 2를 실행하는 새로운 Linux 서버용입니다.


PHP에서는 멀티 바이트 함수 를 사용하거나 mbstring.func_overload 켜야합니다. 그렇게하면 1 바이트 이상을 사용하는 문자가있는 경우 strlen과 같은 기능이 작동합니다.

또한 응답의 문자 집합을 식별해야합니다. 위와 같이 AddDefaultCharset을 사용하거나 헤더를 반환하는 PHP 코드를 작성할 수 있습니다. (또는 HTML 문서에 META 태그를 추가 할 수 있습니다.)


php.ini에서 default_charset 을 설정하는 것 외에도, 출력하기 전에 코드에서 header() 를 사용하여 올바른 charset을 보낼 수 있습니다.

header('Content-Type: text/html; charset=utf-8');

PHP에서 유니 코드로 작업하는 것은 대부분의 문자열 함수가 유니 코드에서 작동하지 않으며 일부 문자열이 완전히 망가질 수 있다는 것을 알고있는 한 쉽습니다. PHP는 "문자"를 1 바이트로 간주합니다. 때로는 괜찮습니다. 예를 들어, explode() 는 바이트 시퀀스를 찾아 구분 기호로 사용합니다. 따라서 실제 문자를 찾지 않아도됩니다. 그러나 실제로 함수가 문자 를 처리하도록 설계된 경우 PHP는 텍스트에 유니 코드에서 찾을 수있는 멀티 바이트 문자가 있는지 전혀 모릅니다.

체크인 할 수있는 좋은 도서관은 phputf8 입니다. 이렇게하면 "나쁜"모든 함수가 다시 작성되므로 UTF8 문자열을 안전하게 작업 할 수 있습니다. mbstring 확장 기능과 같은 확장 기능도 있지만이 기능은 라이브러리를 사용하는 편이 좋지만 라이브러리를 더 많이 사용하기 때문에 라이브러리를 사용하는 것이 더 좋습니다 (그러나 대량 시장 제품을 작성하므로 중요합니다). 그러나 phputf8은 성능 향상을 위해 mbstring을 사용할 수 있습니다.


나는 chazomaticus '우수 답변에 한 가지를 추가하고 싶습니다 :

META 태그도 잊지 마세요 ( HTML4 또는 XHTML 버전 ).

<meta charset="utf-8">

그것은 사소한 것처럼 보이지만, IE7은 이전에 저에게 문제점을 제공했습니다.

나는 모든 것을 올바르게하고 있었다. 데이터베이스, 데이터베이스 연결 및 Content-Type HTTP 헤더가 모두 UTF-8로 설정되었고 다른 모든 브라우저에서 제대로 작동했지만 Internet Explorer는 여전히 "서유럽"인코딩 사용을 주장했습니다.

페이지에서 META 태그가 누락되었습니다. 추가로 문제가 해결되었습니다.

편집하다:

W3C는 실제로 I18N 전용의섹션을 가지고 있습니다. 이 기사에는 HTTP, (X) HTML 및 CSS 측면을 설명하는 다음과 같은 여러 가지 기사가 있습니다.

HTTP 헤더와 HTML 메타 태그 (또는 XML로 제공되는 XHTML의 경우 XML 선언)를 모두 사용하는 것이 좋습니다.


오래된 주제, 알아. PDO를 사용하는 사람과 관련된 문제를 발견했으며 이에 대한 대답은 PDO 연결 문자열에 이것을 사용하는 것이 었습니다.

$pdo = new PDO(
    'mysql:host=mysql.example.com;dbname=example_db',
    "username",
    "password",
    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

내가 이것을 가져간 사이트가 다운되었으므로 운 좋게 Google 캐시를 사용하여 얻을 수있었습니다.


우선 당신이 <5.3PHP이면 아니오. 문제를 해결하는 데 엄청난 문제가 있습니다.

나는 누구도 intl 라이브러리, 유니 코드 , graphemes , 문자열 연산 , 지역화 등을 잘 지원하는 라이브러리에 대해서는 언급하지 않았다는 점에 놀랐다.

PHP 베네룩스 14 에서 엘리자베스 스미스 (Elizabeth Smith)의 slides통해 PHP에서 유니 코드 지원에 대한 정보를 인용 할 것입니다.

INTL

좋은:

  • ICU 라이브러리 주변 래퍼
  • 표준화 된 로케일, 스크립트 별 로케일 설정
  • 숫자 서식 지정
  • 통화 서식
  • 메시지 형식 (gettext 대체)
  • 달력, 날짜, 시간대 및 시간
  • Transliterator
  • 스푸핑 체커
  • 리소스 번들
  • 변환기
  • IDN 지원
  • Graphemes
  • 대조
  • 반복기

나쁜:

  • zend_multibite를 지원하지 않습니다.
  • HTTP 입력 출력 변환을 지원하지 않습니다.
  • 함수 오버로딩을 지원하지 않습니다.

mb_string

  • zend_multibyte 지원을 가능하게합니다.
  • 투명한 HTTP 인 / 아웃 인코딩 지원
  • strtoupper와 같은 funtionallity에 대한 래퍼를 제공합니다.

ICONV

  • 문자 집합 변환을위한 기본
  • 출력 버퍼 핸들러
  • MIME 인코딩 기능
  • 변환
  • 일부 문자열 헬퍼 (len, substr, strpos, strrpos)
  • 스트림 필터 stream_filter_append($fp, 'convert.iconv.ISO-2022-JP/EUC-JP')

데이타베이스

  • mysql : 테이블과 연결에 대한 문자 집합과 데이터 정렬 (데이터 정렬이 아님). 또한 mysql - msqli 또는 PDO를 사용하지 마십시오.
  • postgresql : pg_set_client_encoding
  • sqlite (3) : 유니 코드 및 intl 지원으로 컴파일되었는지 확인하십시오.

다른 일부 잡담들

  • 세 번째 부분 확장을 사용하지 않으면 PHP와 Windows에서 유니 코드 파일 이름을 사용할 수 없습니다.
  • exec, proc_open 및 다른 명령 행 호출을 사용하는 경우 ASCII로 모든 것을 보냅니다.
  • 일반 텍스트는 일반 텍스트가 아니며 파일에는 인코딩이 있습니다.
  • iconv 필터를 사용하여 즉시 파일을 변환 할 수 있습니다.

사물이 추가 된 기능 등을 변경하는 경우이 답변을 업데이트하겠습니다.


제 경우에는 정규 표현식을 사용하는 mb_split 을 사용하고 mb_split . 따라서 mb_regex_encoding('UTF-8'); 을 수행하여 정규 표현식 인코딩이 utf-8인지 수동으로 확인해야했습니다 mb_regex_encoding('UTF-8');

부수적으로, 나는 또한 내부 인코딩이 utf-8이 아니고 mb_internal_encoding("UTF-8"); 을 실행하여 mb_internal_encoding("UTF-8"); 변경했다고 mb_internal_encoding() 을 실행함으로써 발견했다 mb_internal_encoding("UTF-8"); .


최고 대답은 우수합니다. 다음은 정규 debian / php / mysql 설정에서했던 것입니다.

// storage
// debian. apparently already utf-8

// retrieval
// the mysql database was stored in utf-8, 
// but apparently php was requesting iso. this worked: 
// ***notice "utf8", without dash, this is a mysql encoding***
mysql_set_charset('utf8');

// delivery
// php.ini did not have a default charset, 
// (it was commented out, shared host) and
// no http encoding was specified in the apache headers.
// this made apache send out a utf-8 header
// (and perhaps made php actually send out utf-8)
// ***notice "utf-8", with dash, this is a php encoding***
ini_set('default_charset','utf-8');

// submission
// this worked in all major browsers once apache
// was sending out the utf-8 header. i didnt add
// the accept-charset attribute.

// processing
// changed a few commands in php, like substr,
// to mb_substr

그게 전부였다 !


데이터 저장 :

  • 데이터베이스의 모든 테이블 및 텍스트 열에 utf8mb4 문자 세트를 지정하십시오. 이것은 MySQL이 기본적으로 UTF-8로 인코딩 된 값을 물리적으로 저장하고 검색하도록합니다. utf8mb4_* 데이터 정렬이 명시되어 있으면 명시 적 문자 세트없이 MySQL은 암시 적으로 utf8mb4 인코딩을 사용합니다.

  • 이전 버전의 MySQL (<5.5.3)에서는 유감스럽게도 유니 코드 문자의 하위 세트 만 지원하는 utf8 을 사용해야했습니다. 내가 농담했으면 좋겠어.

데이터 액세스 :

  • 응용 프로그램 코드 (예 : PHP)에서 사용하는 DB 액세스 방법에 관계없이 연결 문자 집합을 utf8mb4 로 설정해야합니다. 이렇게하면 MySQL은 네이티브 UTF-8에서 데이터를 애플리케이션으로 넘겨 주거나 그 반대로 변환하지 않습니다.

  • 일부 드라이버는 자체 내부 상태를 업데이트하고 MySQL에 연결에 사용할 인코딩을 알려주는 연결 문자 집합을 구성하기위한 자체 메커니즘을 제공합니다. 이는 일반적으로 기본 접근 방법입니다. PHP의 경우 :

    • PHP 5.3.6 이상의 PDO 추상화 계층을 사용하는 경우 DSN 에서 charset 을 지정할 수 있습니다.

      $dbh = new PDO('mysql:charset=utf8mb4');
      
    • mysqli 사용하고 있다면 set_charset() 호출 할 수 mysqli :

      $mysqli->set_charset('utf8mb4');       // object oriented style
      mysqli_set_charset($link, 'utf8mb4');  // procedural style
      
    • 일반 mysql 하지만 PHP 5.2.3 이상을 실행하는 경우 mysql_set_charset 을 호출 할 수 있습니다.

  • 드라이버가 연결 문자 세트를 설정하는 자체 메카니즘을 제공하지 않는다면, 당신의 애플리케이션이 인코딩 된 연결의 데이터를 기대하는 방식을 MySQL에 알리는 쿼리를 실행해야 할 수도 있습니다 : SET NAMES 'utf8mb4' .

  • utf8mb4 / utf8 에 관한 동일한 고려 사항이 utf8mb4 동일하게 적용됩니다.

출력 :

  • 응용 프로그램이 다른 시스템에 텍스트를 전송하는 경우 문자 인코딩에 대해서도 알려야합니다. 웹 응용 프로그램에서 브라우저는 HTTP 응답 헤더 또는 HTML 메타 데이터를 통해 데이터를 보내는 인코딩에 대해 알려야합니다.

  • PHP에서는 default_charset php.ini 옵션을 사용하거나 수동으로 Content-Type MIME 헤더를 직접 발행 할 수 있습니다.이 헤더는 더 많은 작업이지만 동일한 효과가 있습니다.

입력 :

  • 유감스럽게도, 수신 된 모든 문자열을 올바른 UTF-8로 확인해야만 저장하거나 어디에서나 사용할 수 있습니다. PHP의 mb_check_encoding() 은 트릭을 수행하지만 종교적으로 사용해야합니다. 악의적 인 클라이언트가 원하는 인코딩으로 데이터를 제출할 수 있기 때문에이 문제를 해결할 수있는 방법은 없습니다. PHP를 통해 신뢰할 수있는 방법을 찾을 수있는 트릭을 찾지 못했습니다.

  • 현재 HTML 사양을 읽었을 때, 다음의 글 머리 기호는 현대 HTML에서 필요하지 않거나 더 이상 유효하지 않습니다. 브라우저가 문서에 지정된 문자 세트로 데이터를 처리하고 제출할 것이라는 것을 이해합니다. 그러나 이전 버전의 HTML (XHTML, HTML4 등)을 타겟팅하는 경우 다음 사항이 유용 할 수 있습니다.

    • HTML5 이전의 HTML의 경우 : 브라우저에서 보낸 모든 데이터가 UTF-8이되도록합니다. 불행하게도이 작업을 확실하게 수행하는 유일한 방법은 <form> <form ... accept-charset="UTF-8"> 모든 <form> 태그에 accept-charset 속성을 추가하는 것입니다.
    • HTML5 이전의 HTML의 경우 : W3C HTML 스펙에 따르면 클라이언트는 서버가 제공 한 문자셋으로 서버에 양식을 다시 보내야한다는 것을 기본 설정해야한다고 말합니다. 그러나 이는 분명히 권장 사항 일 뿐이므로 모든 단일 <form> 태그.

기타 코드 고려 사항 :

  • 분명히 게재되는 모든 파일 (PHP, HTML, JavaScript 등)은 유효한 UTF-8로 인코딩되어야합니다.

  • UTF-8 문자열을 처리 할 때마다 안전하게 그렇게해야합니다. 불행히도 이것은 어려운 부분입니다. PHP의 mbstring 확장을 광범위하게 사용하고자 할 것입니다.

  • PHP의 내장 문자열 연산은 기본적으로 UTF-8이 아닙니다 . 일반적인 PHP 문자열 연산 (연결과 같은)으로 안전하게 할 수있는 것들이 있지만 대부분의 경우 동등한 mbstring 함수를 사용해야합니다.

  • 당신이하고있는 일을 알기 위해서는 (UTF-8을 읽고 이해해야합니다.) UTF-8에 대해 알아야합니다. utf8.com 에서 제공하는 링크를 통해 utf8.com 정보를 얻을 수 있습니다.





utf-8