Burada gerçekten iyi cevaplar ve sorunuzu cevaplamaya yönelik girişimler var. Ben bir kodlama ustası değilim, ancak veritabanınıza kadar saf bir UTF-8 yığınına sahip olma arzunuzu anlıyorum . MySQL'in utf8mb4
tablolar, alanlar ve bağlantılar için kodlamasını kullanıyorum .
Durumum "Sadece dezenfektanlarımın, doğrulayıcılarımın, iş mantığımın ve hazır ifadelerimin, veriler HTML formlarından veya e-posta kayıt bağlantılarından geldiğinde UTF-8 ile ilgilenmesini istiyorum." Yani, basit yolumla, şu fikirle başladım:
- Kodlamayı algılamaya çalışın:
$encodings = ['UTF-8', 'ISO-8859-1', 'ASCII'];
- Kodlama tespit edilemezse,
throw new RuntimeException
- Girdi ise
UTF-8
devam edin.
Aksi takdirde, eğer öyleyse ISO-8859-1
veyaASCII
a. UTF-8'e dönüştürme girişimi (bekleyin, bitmedi)
b. Dönüştürülen değerin kodlamasını tespit edin
c. Rapor edilen kodlama ve dönüştürülen değerin ikisi de ise UTF-8
, devam edin.
d. Başka,throw new RuntimeException
Soyut sınıfımdan 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);
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;
}
Kodlama kaygılarını soyut Sanitizer
sınıfımdan ayırmam ve basitçe bir Encoder
nesneyi somut bir alt örneğe enjekte etmem gerektiğine dair bir argüman yapılabilir Sanitizer
. Bununla birlikte, yaklaşımımla ilgili temel sorun, daha fazla bilgi olmadan, istemediğim kodlama türlerini basitçe reddetmemdir (ve PHP mb_ * işlevlerine güveniyorum). Daha fazla araştırma yapmadan, bunun bazı popülasyonlara zarar verip vermediğini (veya önemli bilgileri kaybediyorsam) bilemiyorum. Bu yüzden daha fazlasını öğrenmem gerekiyor. Bu makaleyi buldum.
Metinle çalışmak için her programcının kodlamalar ve karakter kümeleri hakkında kesinlikle ve olumlu olarak bilmesi gerekenler
Ayrıca, e-posta kayıt bağlantılarıma ( OpenSSL
veya kullanılarak mcrypt
) şifrelenmiş veriler eklendiğinde ne olur ? Bu, kod çözmeyi engelleyebilir mi? Peki ya Windows-1252? Güvenlik etkileri ne olacak? Kullanımı utf8_decode()
ve utf8_encode()
de Sanitizer::isUTF8
şüpheli vardır.
İnsanlar PHP mb_ * işlevlerindeki eksikliklere dikkat çektiler. Araştırmak için hiç zaman ayırmadım iconv
, ancak mb_ * işlevlerinden daha iyi çalışıyorsa bana bildirin.