Bir PHP dizesi sadece bir bayt dizisidir ve herhangi bir kodlaması etiketlenmemiştir. Dize değerleri çeşitli kaynaklardan gelebilir: istemci (HTTP üzerinden), veritabanı, dosya veya kaynak kodunuzdaki dize değişmezlerinden. PHP tüm bunları bayt dizileri olarak okur ve hiçbir zaman kodlama bilgisi çıkarmaz.
Tüm veri kaynaklarınız ve hedefleriniz aynı kodlamayı kullandığı sürece, olabilecek en kötü şey dize konumlarının yanlış olmasıdır (çok baytlı kodlamalar kullanıyorsanız), PHP karakterleri değil, baytları sayacaktır.
Ancak kodlamalar eşleşmezse (örneğin, UTF-8 olarak depolanan bir kaynak dosyaya bir dize hazır bilgisi yazıp Latin-1'i bekleyen bir veritabanına gönderirseniz), PHP sizin için herhangi bir dönüşüm gerçekleştirmez: baytları ham olarak mutlu bir şekilde kopyalayın.
En kolay çözüm şudur:
- PHP'nin dahili kodlamasını UTF-8 olarak ayarlayın.
- Tüm kaynak dosyalarınızı UTF-8 olarak kaydedin.
- Çıktı kodlamanız olarak UTF-8 kullanın (uygun
Content-type
başlıkları göndermeyi unutmayın ).
- Veritabanı bağlantısını UTF-8 kullanacak şekilde ayarlayın (
SET NAMES UTF8
MySQL'de).
- Mümkünse diğer her şeyi UTF-8 olacak şekilde yapılandırın.
- Kontrol edemediğiniz herhangi bir şey için (örn. Üçüncü taraf web hizmetleri), kodlamayı bildiğinizden emin olun ve mümkün olduğunca erken UTF-8'e ve diğer kodlamaya geri dönün.
Neden UTF-8? Tüm Unicode karakterleri temsil edebildiğinden ve böylece mevcut tüm 7 bit ve 8 bit kodlamaların yerini aldığından ve ASCII ile ikili uyumlu olduğu için, yani her geçerli ASCII dizesi de geçerli bir UTF-8 dizesidir (ancak vv değil) .).
Örneğinizde, olan budur.
İlk olarak, kaynak dosyanızı kaydedin; metin düzenleyiciniz muhtemelen UTF-8 kullanacak şekilde yapılandırılmıştır, bu nedenle dize hazır bilginiz diskte UTF-8 olarak kodlanır. PHP dizeyi bir bayt dizisi olarak yorumlayarak bu dosyayı okur; $original
şimdi sadece bir bayt dizisi olan 7 karakterden oluşan UTF-8 kodlu bir dizeye sahiptir (her karakter iki veya daha fazla bayt ile temsil edildiğinden, 7 bayttan fazlasını içermesine rağmen). Daha sonra ararsanız echo $original
, kodlanmış dize istemciye olduğu gibi gönderilir; istemciye UTF-8'i beklemesini söylediyseniz, her şey yolundadır, ancak yapmadıysanız, PHP'nin farkı söylemenin bir yolu yoktur ve tarayıcıda çöp ile sonuçlanırsınız. Bir deneme olarak şunu deneyin:
$original = "शक्नोम्यत्तुम्";
echo strlen($original);
strlen
kodlama-agnostiktir ve sabit genişlikli 8 bit kodlamayı, yani karakter başına bir bayt olduğunu varsayar, böylece karakterleri değil baytları sayacaktır.