2012-02-02 1 views
8

MySql 데이터베이스에 직렬화하고 저장하려는 큰 PHP 객체가 있습니다. 테이블 인코딩은 UTF-8이고 직렬화 된 개체 인코딩을 보유 할 열도 UTF-8입니다.MySql 데이터베이스에 직렬화 된 객체 저장

문제는 개체가 프랑스어 문자를 포함하는 텍스트 문자열을 보유하고 있다는 것입니다. 예를 들어

:

Merci d'avoir passé commande avec Lovre. Voici le récapitulatif de votre commande 

I 객체를 직렬화

다음 그것을를 unserialize 다시 직접 문자열 유지 올바른 형식이다. 내가 MySQL 데이터베이스에 직렬화 된 객체를 저장할 때

그러나 다음 다음 다시 검색 문자열은 다음과 같이된다 그것을를 unserialize : 나는 데이터베이스에 객체를 저장할 때

Merci d'avoir passé commande avec Lovre. Voici le récapitulatif de votre commande 

뭔가 잘못.

주 :

  • 개체가 ORM을 추진하여 저장됩니다.
  • 열 유형은 text입니다.
  • 문자열이 html 파일에서 저장되고 읽혀집니다.
+0

파일의 인코딩은 무엇입니까? – alexn

+0

base_64로 인코딩 할 수는 있지만 그렇게하지 않아도됩니다. 데이터베이스 컬럼은 어떤 타입입니까? PHP에서 데이터베이스 연결 설정을 확인 했습니까? –

+0

@ TheSilencer 데이터베이스 열 유형은 텍스트입니다. 데이터베이스 연결은 PROPEL을 사용하여 수행됩니다. – Songo

답변

10

serialize으로 생성 된 문자열은 이진 문자열이며 특정 문자 집합 인코딩이 없지만 바이트의 "배열"(한 바이트는 8 비트, 한 옥텟)입니다.

이제이 문자열을 가져 와서 LATIN-1로 인코딩되었음을 데이터베이스에 알리고 데이터베이스가 UTF-8 인코딩을 사용하는 텍스트 필드에 저장하면 데이터베이스는 LATIN-1의 인코딩을 투명하게 LATIN-1의 인코딩으로 변경합니다 UTF-8. UTF-8은 일부 문자에 대해 문자 당 1 바이트 이상을 사용하는 문자 집합 인코딩입니다 (예 : é과 같이 질문 할 때 사용).

문자 éé이어서위한 UTF-8 바이트 시퀀스 인 데이터베이스 내부 é로서 저장된다.

필요한 인코딩을 지정하지 않고 데이터베이스에서 데이터를 가져 오면 데이터베이스에서이를 UTF-8로 반환합니다.

이제 unserialize에는 이진 문자열이 유효하지 않게 변경 되었기 때문에 문제가 있습니다.

대신에 데이터베이스에 직렬화 된 문자열을 저장할 때 인코딩을 수정해서는 안된다는 사실을 알려야합니다. 올바른 열 형식과 인코딩 (이진 필드, BLOB - Binary Large Object­MySQL Docs, Binary Types­Propel Docs 참조)을 선택하면 데이터베이스에서 데이터를 가져올 때 charset 인코딩을 다시 원래 형식으로 되돌릴 수 있습니다. 첫 번째 방법 (바이너리 필드)은 사용자가 찾고자하는 것이기 때문에 더 좋습니다.

데이터베이스에 이미 잘못된 형식으로 저장된 데이터의 경우 데이터를 수정해야합니다. 이를 위해 먼저 어떤 재 인코딩이 적용되었는지 알아야합니다 (예 : 어느 캐릭터 셋으로부터 어느 캐릭터 셋에의 캐릭터 셋. LATIN-1이라고 추측하지만 보증은 없습니다. 찾으려는 현재 응용 프로그램 데이터 및 프로세스의 인코딩을 검토해야합니다.

알아 낸 사항은 UTF-8에서 원래 인코딩으로 되돌려 인코딩하십시오.

+0

나는 당신이 말한 것을 시도하고 열 유형을 BLOB로 변환했지만 문제는 여전히 지속됩니다.그러나 데이터베이스에서 객체를 검색 한 후 메시지 자체를 'utf_decode'하기로 결정하고 그 문제를 해결했습니다. – Songo

+0

기존 데이터 및/또는 새 데이터에 대해 지속됩니까? 또한 저는 프로펠러 전문가가 아니지만 데이터베이스 계층에 대한 직접적인 솔루션이 있어야하므로 애플리케이션 로직 코드 내에서 인코딩을 신경 쓸 필요가 없습니다. 데이터베이스 계층에서 그것을 해결할 수 없다면, 코드를 깨끗하게 유지하는 데 도움이되는 PHP의 ['Serializable'] (http://php.net/Serializable) 인터페이스가 있습니다. – hakre

+0

아직 개발 단계에 있으므로 기존 데이터가 없습니다. 나는 PROPEL 구성을 점검하고 연결에 UTF-8을 사용합니다. 어쩌면 내가 놓친 뭔가가있을 수도 있지만, 언급 한 Serializable 인터페이스를 살펴볼 것이다. 당신의 도움을 주셔서 감사합니다. – Songo

4

어디서나 utf-8 을 사용하십시오. - 놓친 것처럼 들립니다.

귀하의 경우에는 데이터베이스 연결 (SET NAMES 문 또는 mysql_set_charset())을 사용하여 올바른 문자셋을 설정하는 것을 잊어 버렸다고 생각합니다. 그러나 코드를 보지 않고 말하기는 어렵습니다.). 다음

당신이 알아서해야 모든 점을 나열 UTF-8 all the way through에 완벽한 해답을 주신 chazomaticus에서 인용한다 :

저장 :

  • 이 (utf8_unicode_ci 지정 또는 해당) 모든 테이블 의 데이터 정렬 및 데이터베이스의 텍스트 열. 이것은 MySQL을 물리적으로 저장하고 값을 기본적으로 UTF-8로 검색합니다.

검색 : PHP에서

  • , 당신은 사용, 당신은 UTF8로 연결 문자 집합을 설정해야합니다 어떤 DB 래퍼. 이렇게하면, MySQL은 이 네이티브 UTF-8 에서 데이터를 PHP로 전달할 때 변환을하지 않습니다. 당신은 DB 래퍼를 사용하지 않는 경우, 당신은 아마 당신에게 UTF-8 결과를 제공하기 위해 MySQL을 알려 쿼리를 실행해야한다는 * 참고 : SET NAMES 'utf8' (즉시 연결로).

납품 : 당신은 클라이언트에 적절한 헤더를 제공하기 위해 PHP에게있어

  • , 그래서 텍스트가 UTF-8로 해석됩니다. PHP에서는 그냥 더 많은 작업이지만 같은 효과가있는 Content-Type 헤더 자신을 발행 수동으로 default_charset php.ini의 옵션을 사용하거나 할 수 있습니다.

제출 :

  • 당신은 UTF-8로 브라우저로 전송 된 모든 데이터를 원한다. 불행히도 에 대한 유일한 방법은 accept-charset 속성을 모든 <form> 태그에 추가하는 것입니다 : <form ... accept-charset="UTF-8">. W3C의 HTML 사양이 클라이언트가 "해야"기본 서버에 다시 형태를 보내기에 어떤 에 서버가 제공 캐릭터 세트, 그러나 이것은 분명히 단지 추천, 명시 적 존재에 대한 따라서 필요는 것을 말한다
  • 주 모든 <form> 태그가 개 있습니다.
  • 은 을 유효 UTF-8로 확인하려고 시도하기 전에 을 저장하거나 어디에서든지 사용하려고합니다. PHP의 mb_check_encoding()은 속임수가 이지만 종교적으로 사용해야합니다.

처리 :

  • 이는 불행하게도, 하드 부분이다. UTF-8 문자열을 처리 할 때마다 안전하게 그렇게해야합니다. 을 수행하는 가장 쉬운 방법은 PHP의 mbstring 확장을 광범위하게 사용하는 것입니다.
  • PHP의 문자열 연산은 기본적으로 유효하지 않습니다. UTF-8 safe. 은 정상적인 PHP 문자열 작업 (연결과 같은)에서 안전하게 수행 할 수 있지만, 은 대부분 동등한 mbstring 함수를 사용해야합니다. 으로
  • 당신이 무슨 일을하는지 알고 (읽기 : 엉망 그것을), 당신이 정말로 알 필요가 UTF-8 과 가장 낮은 가능한 수준에서 작동하는 방법. 링크 중 일부를 utf8.com에서 확인하고 리소스를 확인하여 필요한 모든 것을 알아보십시오. 알아 두십시오. 이 그것이 명백한 것처럼 보일 수도 하지만, 어딘가 말했다되어야처럼
  • 또한, 느낌 : 모든 PHP 또는 HTML은 당신이 제공됩니다 파일이 유효한 UTF-8로 인코딩해야합니다.당신이 UTF-8을 사용할 필요가 없습니다

주 - 중요한 부분은있을 그 어떤 캐릭터 세트의 독립적 인 같은 캐릭터 세트 어디서나, 사용하는 것입니다. 하지만 어쨌든 일을 변경해야한다면 utf-8을 사용하십시오.

1

저는 항상 base64_encode()을 사용하여 이미지 데이터를 저장하고 있습니다. 직렬화 된 데이터로 인해 때때로 문제가 발생하지만 base64 값을 사용한 후에는 단순한 문자 만 남아 있습니다.

1

serialize하는 대신 json_encode을 사용하는 것이 좋습니다. 언젠가 PHP가 아닌 다른 장소에서 그 데이터를 사용하려고 시도하고 JSON에 저장하면 어디서나 읽을 수 있습니다. 거의 모든 언어가 JSON의 해독을 지원하며 잘 정착 된 표준입니다.

어디서나 utf8을 사용하는 것에 대한 답이 있습니다! :-D

+0

좋은 생각이 아닙니다. 1. 그것은 배열을 객체로 바꾼다. 2. 클래스 타입과 메소드는 잃어버린다. –

+0

메소드는 어쨌든 없어져서 ....'serialize' 호출로 저장하지 않는다. 나를 믿어라. 직렬화 된 것을 저장하는 것이 더 나쁘다. 결국 다른 곳에서 그 물건을 읽어야 할 것입니다. 클래스로 다시 역 직렬화해야하는 경우 형식을 문자열로 저장 한 다음 나중에 json 데이터를 필드로 사용하여 적절한 클래스를 인스턴스화하고 모든 ORM이 기본적으로 DB 레코드와 마찬가지로 일반 JSON을 반환하도록 전환합니다. –