UTF-8 tüm yol boyunca

12 Cevap php

Ben yeni bir sunucu kurma, ve benim web uygulaması tam UTF-8 desteklemek istiyor değilim. Ben mevcut sunucularda geçmişte denenmiş ve her zaman ISO-8859-1 geri düşmek zorunda sona görünüyorlar.

Tam olarak nerede ben kodlama / charsets ayarlamak gerekiyor? Ben bunu yapmak için Apache, MySQL ve PHP yapılandırmanız gerekebilir farkında değilim - Ben takip veya uyuşmazlığı nerede belki giderebilirsiniz bazı standart bir kontrol listesi var mı?

Bu MySQL 5, PHP 5 ve Apache 2 çalışan, yeni bir Linux sunucu içindir.

12 Cevap

Data Storage:

  • Veritabanındaki tüm tablolar ve metin sütunlarında set utf8mb4 karakterini belirtin. Bu MySQL fiziksel depolamak ve UTF-8 özgün olarak kodlanmış değerleri almak yapar. Bir utf8mb4_* harmanlama (herhangi bir açık karakter set vermeden) belirtilmiş ise MySQL örtülü utf8mb4 kodlamasını kullanacağını unutmayın.

  • MySQL (<5.5.3) eski sürümlerinde, ne yazık ki sadece Unicode karakter bir alt kümesini destekler, sadece utf8 kullanmak zorunda olacak. Ben şaka olsaydı.

Data Access:

Output:

Input:

Other Code Considerations:

Ben bir şey eklemek istiyorum chazomaticus' excellent answer:

: META (Bu gibi, ya da the HTML4 or XHTML version of it) etiketi ya da unutma

<meta charset="utf-8">

Bu önemsiz gibi görünüyor, ancak IE7 önce bana o sorunları vermiştir.

Ben her şeyi doğru yaptığımı; veritabanı, veritabanı bağlantısı ve Content-Type HTTP başlık tüm UTF-8 olarak ayarlanmış olduğunu, ve diğer tüm tarayıcılarda iyi çalıştı, ancak Internet Explorer hala "Batı Avrupa" kodlamasını kullanarak ısrar etti.

Bu sayfa META etiketi eksik çıktı. Sorunu çözüldü sözlerine ekledi.

Edit:

W3C aslında oldukça büyük bir section dedicated to I18N vardır. Onlar bu konu ile ilgili makaleler bir dizi var - HTTP açıklayan, (X) HTML ve CSS şeyler tarafı:

Onlar HTTP başlık ve HTML meta tag (veya XML beyanı XHTML XML olarak görev durumunda) hem de kullanmanızı öneririz.

Php.ini içinde default_charset ayarlamaya ek olarak, herhangi bir çıktı önce, kod içinde header() kullanarak doğru charset gönderebilirsiniz:

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

PHP Unicode ile çalışmak sürece farkında olarak kolay olduğunu string functions don't work with Unicode, and some might mangle strings completely çoğu. PHP 1 byte uzunluğundaki "karakter" düşünüyor. Bazen bu (- bu yüzden sizin için bakmak ne gerçek karakterler önemli değil, örneğin, explode() sadece bir bayt dizisi arar ve bir ayırıcı olarak kullanır) tamamdır. Ama işlevi aslında characters, PHP metin Unicode ile bulunur çoklu-bayt karakterler var hiç bir fikrim var üzerinde çalışmak için tasarlanmıştır diğer zamanlarda.

Denetlemek için iyi bir kütüphanesi phputf8. Güvenle UTF8 dizeleri üzerinde çalışmak, böylece bu "kötü" tüm fonksiyonları yeniden yazar. Orada da, sizin için bunu yapmak için denemek Mbstring uzantısı gibi uzantıları vardır, ama daha taşınabilir çünkü ben kütüphanesini kullanarak tercih (ama bu benim için önemli bu yüzden, toplu pazar ürünleri yazma). Ama phputf8 performansı artırmak için, yine de, perde arkasında mbstring'i kullanabilirsiniz.

Eski bir konu, biliyorum. PDO ve cevap kullanarak birisi PDO Bağlantı dizesi için kullanmak oldu bir sorun bulundu:

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

Ben bu aldı site kapalı, neyse google önbelleğini kullanarak almak mümkün oldu.

Benim durumumda, ben regex kullanan, mb_split kullanıyordum. Bu nedenle de elle emin regex kodlama edildi utf-8 yaparak mb_regex_encoding('UTF-8'); yapmak zorunda

Bir yan not olarak, ben de dahili kodlamayı utf-8 değil, ve ben o çalıştırarak mb_internal_encoding("UTF-8"); değişti mb_internal_encoding() çalıştırarak keşfetti.

PHP olarak, multibyte functions kullanmanız ya da gerek, ya da mbstring.func_overload açmak gerekir. Eğer birden fazla bayt almak karakter varsa bu şekilde strlen gibi şeyler çalışacaktır.

Ayrıca yanıtları karakter kümesi tanımlamak gerekir. Yukarıdaki gibi, AddDefaultCharset kullanın, ya da başlık döndüren PHP kodu yazabilirsiniz ya. (Ya da HTML belgeleri bir META etiketi ekleyebilirsiniz.)

Baştan olması iyi bir hedef - sitenizin niteliğine göre, Googling bu konuda çok sayıda kaynak buldum - tabii ki, onunla başa çıkmak için ilk değilsin.

Mistik PHP6 tamam, bu dışarı doğruldu olması gerekiyordu?

Hemen hemen sunucu düzeyinde mysql için global varsayılan charset utf-8 ayarlayabilirsiniz ve daha taneli seviyelere doğru varsayılan olacaktır.

PHP Unicode desteği hala büyük bir karmaşa. O utf8 (dahili olarak kullanır) bir ISO8859 dize dönüştürme yeteneğine sahip olsa da, tüm dize işleme fonksiyonları dizeleri cendereye ve bozuk olacak demektir, özgün unicode dizeleri ile çalışmak yeteneği yoksun. Yani kendinize uygun utf8 desteği için ayrı bir kütüphane kullanımı, veya tüm string işleme fonksiyonları yeniden yazmak ya var.

Kolay kısmı sadece HTTP başlıkları ve veritabanı ve böyle charset belirterek, ancak PHP kodu çıkışı geçerli UTF8'i değilse hiçbiri önemli değil. Bu zor kısmı, ve PHP orada size hemen hemen hiç yardım verir. (Ben PHP6 bu kötü düzeltmek gerekiyordu düşünüyorum, ama bir süre uzakta hala)

Her şeyden önce siz iseniz < 5.3PHP sonra hayır. Sen mücadele sorunların bir ton var.

I, hiçbiri intl library, the one that has good support for unicode, graphemes, string operations, localisation ve çok daha fazla söz konusu olduğunu sürpriz aşağıya bakın.

I PHPBenelux'14 at Elizabeth Smith's slides tarafından PHP unicode desteği hakkında bazı bilgiler aktaracağım

INTL

Şunun için iyi:

  • YBÜ kütüphane etrafında sarıcı
  • Komut başına Standartlaştırılmış yerel, set yerel
  • Biçimlendirme Sayı
  • Döviz biçimlendirme
  • Mesaj biçimlendirme (gettext değiştirir)
  • Takvimler, tarihler, zaman dilimi ve zaman
  • Transliterator
  • Spoofchecker
  • Kaynak demetleri
  • Dönüştürüler
  • IDN desteği
  • Grafemler
  • Karşılaştırma
  • Yineleyicilerde

Kötü:

  • Zend_multibite desteklemiyor
  • Does not support HTTP input output dönüştürme
  • Fonksiyon aşırı yükleme desteklemiyor

mb_string

  • Zend_multibyte desteğini etkinleştirir
  • Şeffaf HTTP giriş / çıkış kodlamayı destekler
  • Böyle strtoupper gibi funtionallity için bazı korumalar sağlar

ICONV

  • Karakter kümesi dönüştürme için birincil
  • Çıktı tamponu eylemcisi
  • mim kodlama işlevselliği
  • dönüştürme
  • Bazı dize yardımcıları (len, substr, strpos, strrpos)
  • Stream Filter stream_filter_append($fp, 'convert.iconv.ISO-2022-JP/EUC-JP')

DATABASES

  • mysql: Karakter ve tablolar ve bağlantı (değil harmanlama) üzerinde harmanlama. Msqli veya PDO - Ayrıca mysql kullanmayın
  • postgresql: pg_set_client_encoding
  • sqlite (3): emin unicode ve intl desteği ile derlenmiş olun

Some other Gotchas

  • Eğer 3 parça uzantısını kullanmak sürece PHP ve pencereler ile unicode dosya adları kullanamazsınız.
  • Eğer exec, proc_open ve diğer komut satırı aramaları kullanıyorsanız ASCII şeyi Gönder
  • Düz metin düz metin değil, dosyalar kodlamalar
  • Sen iconv filtre ile anında dosyalarını dönüştürebilirsiniz

Ben şeyler çok da eklendi özelliklerini değiştirebilir ve durumda bu cevabı güncellemek edeceğiz.

Geçenlerde kullanarak strtolower() verileri özel bir karakter sonra kesilir sorunlarına neden olabilir keşfetti.

Çözelti kullanmaktı mb_strtolower($string, 'UTF-8');

(Ki yavaş ama bir çözümdür)

Üst cevabı mükemmel. Burada normal bir debian / php / mysql kurulumu hakkında buydu:

// 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

tüm!