PHP MySQL yaptığı aynı şekilde dizeleri Karşılaştırılması

5 Cevap php

Ben bir utf8 MySQL tabloda varchar depolanması ve utf8_general_ci harmanlama kullanıyorum. Ben varchar benzersiz bir dizin var. Ben MySQL endeksi üzerinde ne yapacağını eşdeğer PHP bir dize karşılaştırma yapmak istiyorum.

Spesifik bir örnek ben bu gerçekleşmeden önce 'bir' PHP 'A' eşdeğer kabul olduğunu tespit edebilmek istiyorum ki:

mysql> insert UniTest (str) values ('a');                                   
Query OK, 1 row affected (0.00 sec)

mysql> insert UniTest (str) values ('À');                                   
ERROR 1062 (23000): Duplicate entry 'À' for key 1

5 Cevap

Harmanlama depolama ile ilgisi yoktur. Sen depolama kodlamasını belirlemek için charset ayarlamanız gerekir. Harmanlama karşılaştırma ve sıralama gerçekleşmesi gerektiğini nasıl yönetir. Harmanlama farkında charset gerekir, ancak aksi takdirde charset ile ilgisi yoktur.

Sorunuzu yanıtlamak için, iconv metni translitter için kullanmak ve sonra karşılaştırabilirsiniz. Örneğin:

function compare($s1, $s2) {
  return strcmp(
    iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $s1),
    iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $s2));
}

Daha hızlı muhtemelen rağmen bu, MySQL sizin için ne yapacağını temelde ve ISO-8859-1//TRANSLIT biraz farklı bir harmanlama tablosu olabilir. Bu konuda tamamen emin değil.

Muhtemelen diğerleri zaten önerilen gibi olsa veritabanını kullanmak daha kolay olacaktır.

Neden sadece MySQL zaten aynı anahtar ile bir rekor olup olmadığını karar versin değil mi?

Bu niteliği ile bir rekor zaten var olup olmadığını sormak için SELECT sorgu çalıştırabilir:

SELECT 1
FROM UniTest
WHERE str = "À"

Yoksa sadece ona yeni kayıt ekleme denemek ve bir hata oluştu görmek için fonksiyonları mysql_error() ve mysql_errno() kullanın.

Sadece MySQL gibi bir MySQL sorgu göndererek, çalışma yapalım mantıklı olacaktır:

SELECT CASE WHEN '$a' = '$b' THEN 1 ELSE 0 END


EDIT post clarification:

Bir kerelik kendisine katıldı faiz Kartezyen tüm karakter kümesi yineleme ve denklik setleri standart bir php ilişkisel dizi oluşturabilir.

    for each $char1 in $charset {  
        for each $char2 in $charset {  
            $charmatch[$char1][$char2] = mysqlTestMatch($char1, $char2));  
        }  
    }  

Sonra bir) aynı, ya da değilse, b) eşdeğer olup olmadığını görmek için, karakteri ile her dize karakterini test etmek gerekiyordu.

Ben bunu doğru olsun eğer MySQL bir UTF-8 Genel indisleri karşı bir çek alacağı gibi Yani, PHP karşılaştırmak benzer yapmak istiyorum?

Kolay şey, bir baz mektupta bazı harfler dönüştürmek için esas MySSQL tarafından kullanılan utf8_general_ci kurallarına göre bir dize dönüştürmek olacak bir yardımcı işlev oluşturmak olacaktır.

Bu MySQL harmanlama için kurallar burada listelenir:

http://www.collation-charts.org/mysql60/mysql604.utf8_general_ci.european.html

Eğer soldaki "altın A" sadece biraz aşağı kaydırma Örneğin, o A'ya dönüştürülür olsun tüm karakterleri görürsünüz

Örneğin adlı bir yardımcı işlev, verilen utf8g_to_ascii(), bir fonksiyon yazabiliriz:

function utf8_compare($s1, $s2) {
   $a = utf8g_to_ascii($s1);
   $b = utf8g_to_ascii($s2);
   return strcmp( $a, $b );
}

Ben sonra benim kod modeli olacaktır:

http://dev.splitbrain.org/view/darcs/dokuwiki/inc/utf8.php

Intl en Collator veya Transliterator kullanın.

$s1 = 'a';
$s2 = 'À';

var_dump(
    is_same_string($s1, $s2),
    $s1 === transliterator_transliterate('Any-Latin; Latin-ASCII; Lower()', $s2)
);

function is_same_string($str, $str2, $locale = 'en_US')
{
    $coll = collator_create($locale);
    collator_set_strength($coll, Collator::PRIMARY);  
    return 0 === collator_compare($coll, $str, $str2);
}