سؤال

وأنا تخزين VARCHAR في جدول UTF8 الخلية واستخدام utf8_general_ci الترتيب. لدي فهرس فريد على VARCHAR. أود أن تفعل مقارنة سلسلة في PHP أن ما يعادل ماذا سيفعل الخلية على المؤشر.

وهناك مثال محدد هو أنني أردت أن تكون قادرة على الكشف عن أن "أ" ويعتبر ما يعادل 'A' في PHP قبل أن يحدث هذا:

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
هل كانت مفيدة؟

المحلول

وهذا الترتيب ليس له اي علاقة مع تخزين أي شيء. تحتاج إلى تعيين محارف لتحديد الترميز تخزين. ترتيب يحكم كيفية المقارنة والفرز يجب أن يحدث. يجب محارف ترتيب علم، لكن على خلاف ذلك لا علاقة له مع محارف لا شيء.

لإجابة على سؤالك، يمكنك استخدام iconv إلى translitter النص، ومن ثم مقارنتها. على سبيل المثال:

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

وهذا هو في الأساس ما سوف الخلية القيام به بالنسبة لك، على الرغم من انها ربما أسرع، وأنه قد يكون لها جدول ترتيب مختلف قليلا من ISO-8859-1//TRANSLIT. لست متأكدا تماما عن ذلك.

وربما يكون من الأسهل استخدام قاعدة البيانات رغم ذلك، كما فعل آخرون قد اقترح بالفعل.

نصائح أخرى

لماذا لا مجرد السماح الخلية تقرر ما إذا كان هناك بالفعل رقما قياسيا مع نفس المفتاح؟

هل يمكن تشغيل استعلام SELECT إلى التساؤل عما إذا كان هناك بالفعل رقما قياسيا مع هذه السمة:

SELECT 1
FROM UniTest
WHERE str = "À"

وأو كنت مجرد محاولة إعطائها إدخال السجل الجديد واستخدام وظائف <لأ href = "http://docs.php.net/manual/en/function.mysql-error.php" يختلط = "نوفولو noreferrer "> mysql_error () و mysql_errno () لمعرفة ما إذا حدث خطأ.

هل من المعقول لمجرد السماح الخلية للقيام بهذا العمل، عن طريق تقديم استعلام إلى الخلية مثل:

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


آخر تحرير التوضيح:

هل يمكن لمرة واحدة أعاد من خلال مجموعة الحرف بأكمله من الديكارتية الفائدة انضم لنفسها وبناء مجموعة بي إتش بي النقابي القياسية للمجموعات التكافؤ.

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

وبعد ذلك كنت بحاجة لاختبار كل حرف سلسلة بحرف، لمعرفة ما إذا أ) كانت هي نفسها، أو إذا لم يكن كذلك، ب) أنهم ما يعادلها.

وهكذا، إذا كان يمكنني الحصول عليه بشكل صحيح، وتريد أن تفعل ما شابه مقارنة في PHP كما ستحصل في الاختيار ضد UTF-8 العام الاختيار المؤشر في الخلية؟

وأسهل شيء سيكون على إنشاء وظيفة مساعد التي من شأنها أن تحويل سلسلة فقا لقواعد utf8_general_ci يستخدمه MySSQL، الذي هو أساسا إلى تحويل بعض رسائل إلى بريد إلكتروني القاعدة.

وقواعد لأن الخلية الترتيب يتم سرد هنا:

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

وعلى سبيل المثال، إذا كنت انزل قليلا إلى "الذهب A" على اليسار، سترى جميع الشخصيات التي تحصل على تحويلها إلى أنه A.

وبالنظر إلى وظيفة مساعد، ودعا على سبيل المثال utf8g_to_ascii()، هل يمكن كتابة دالة:

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

وأود أن نموذج قانون بلدي بعد:

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

استخدم Collator تي أو Transliterator.

$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);
}
scroll top