في PHP، كيف يمكنني التعامل مع الفرق في أسماء الملفات المشفرة على HFS + مقابل أي مكان آخر؟

StackOverflow https://stackoverflow.com/questions/773574

سؤال

أنا أقوم بإنشاء بحث ملف بسيط للغاية، حيث توجد قاعدة بيانات البحث ملف نصي مع اسم ملف واحد لكل سطر. تم تصميم قاعدة البيانات مع PHP، ويتم العثور على التطابقات بواسطة Grepping الملف (أيضا مع PHP).

هذا يعمل بشكل رائع في لينكس، ولكن ليس على Mac عند استخدام أحرف غير ASCII. وبعد يبدو أن الأسماء ترمز بشكل مختلف عن HFS + (ماكوسكس) من على سبيل المثال Ext3 (Linux). إليك Test.php:

<?php
$mystring = "abcóüÚdefå";
file_put_contents($mystring, "");
$h = dir('.');
$h->read(); // "."
$h->read(); // ".."
$filename = $h->read();

print "string: $mystring and filename: $filename are ";

if ($mystring == $filename) print "equal\n";
else print "different\n";

عند تشغيل ماكوسكس:

$ php test.php
string: abcóüÚdefå and filename: abcóüÚdefå are different
$ php test.php |cat -evt
string: abcóü?M-^Zdefå$ and filename: abco?M-^Au?M-^HU?M-^Adefa?M-^J are different$

عند تشغيلها على Linux (أو على نظام ملفات Ext3 مثبت على NFS على ماكوسكس):

$ php test.php
string: abcóüÚdefå and filename: abcóüÚdefå are equal
$ php test.php |cat -evt
string: abcM-CM-3M-CM-<M-CM-^ZdefM-CM-% and filename: abcM-CM-3M-CM-<M-CM-^ZdefM-CM-% are equal$

هل هناك طريقة لجعل هذا البرنامج النصي "متساو" على كلا النظامين؟

هل كانت مفيدة؟

المحلول

يستخدم MacosX نموذج التطبيع D (NFD) لتشفير UTF-8، في حين معظم الأنظمة الأخرى تستخدم NFC.

NFC vs NFD

(من Unicode.org.)

هناك العديد من التنفيذ على NFD لتحويل NFC. لقد استخدمت PHP الطبقة الطبيعية للكشف عن سلاسل NFD وتحويلها إلى NFC. انها متوفرة في PHP 5.3 أو من خلال امتداد تدويل Pecl. وبعد التعديل التالي سيجعل عمل البرنامج النصي:

...
$filename = $h->read();
if (!normalizer_is_normalized($filename)) {
   $filename = normalizer_normalize($filename);
}
...

نصائح أخرى

يبدو أن Mac OS X / HFS + يستخدم مجموعات الأحرف بدلا من الأحرف الفردية. لذلك ó (u + 00f3) هو ترميز بدلا من ذلك o (u + 006f) + ´ (u + cc81، والجمع بين اللكنة الحادة). أنظر أيضا جدول تحلل يونيكود أبل.

هل راجعت أن كلا النظم يستخدمان نفس اللغة؟

ما الترميز هو البرنامج النصي PHP باستخدام كلا النظامين؟

أود أيضا أن أحاول استخدام strcmp. بدلا من المشغل يساوي. لست متأكدا مما إذا كان المشغل يساوي يستخدم strcmp داخليا، لكنه شيء بسيط لاختباره في قضيتك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top