ترميز مشكلة مع preg_replace () والاستسلالات ()
-
20-09-2019 - |
سؤال
<?php
$file = 'siësta.doc';
echo preg_replace("/[^a-zA-Z0-9.]/u", '_', $file);
// Output: si_sta.doc
?>
ولكن إذا قرأت أسماء الملفات باستخدام Scandir، فقد حصلت على تحويلات غريبة:
<?php
$files = scandir(DIRNAME);
foreach ($files as $file) {
echo preg_replace("/[^a-zA-Z0-9.]/u", '_', $file);
// Output for the file above: sie_sta.doc
}
?>
حاولت الكشف عن الترميز، اضبط الترميز، وتحويله باستخدام وظائف ICONV. حاولت وظائف MB_ أيضا. لكنه كان أسوأ فقط. أي خطأ ارتكبت؟
شكرا لك مقدما
المحلول
مثير للاهتمام. بعد إعادة تشغيل بعض الشيء وجدت أن OSX يخزن أسماء الملفات "Unicode متحللة" (انظر http://developer.apple.com/mac/library/qa/qa2001/qa1173.html.). وهذا هو، "ë" تمثل ك "E" + رمز الحسم (0xcc88).
نصائح أخرى
لقد حاولت UTF8_Encode؟ (يعمل على ويندوز على الأقل)
<?php
$files = scandir(DIRNAME);
foreach ($files as $file) {
echo preg_replace("/[^a-zA-Z0-9.]/u", '_', utf8_encode($file));
// Output for the file above: sie_sta.doc
}
?>
المشكلة هي التواصل بين Windows و PHP. ليس من الممكن الحصول على أسماء ملفات Unicode، لأنها تعتمد على لغة تطبيق Windows غير Unicode.
أفضل حل هو تنفيذ أمر DIR وحصل على معلومات معالجتها، ولكن يجب عليك القيام بذلك من خلال CMD، والحصول على أسماء Windows Short:
chcp 65001
dir /x c:\test\ > myinfo.txt
يعود:
El volumen de la unidad C es Windows8_OS
El número de serie del volumen es: 14A3-025F
Directorio de C:\test
22/12/2015 22:11 <DIR> .
22/12/2015 22:11 <DIR> ..
22/12/2015 22:12 0 a.txt
22/12/2015 22:10 <DIR> English
22/12/2015 22:10 <DIR> ESPAOL~1 Español
22/12/2015 22:11 <DIR> 8311~1 ру́сский язы́к
22/12/2015 22:10 <DIR> _0B41~1 عربي ,عربى
22/12/2015 22:10 <DIR> 8F4C~1 北方話
1 archivos 0 bytes
7 dirs 839.672.786.944 bytes libres
ثم، يمكنك قراءة myinfo.txt للحصول على الاتصال بين الاسم الأصلي واسم Windows Short.
تعمل بعض وظائف PHP على ما يرام بأسماء قصيرة ويمكنك بناء وتجميع كما لو كنت بحاجة إلى عرضها:
$array['short_name']= $original_name;
علي سبيل المثال: is_dir, is_file
يعمل بشكل جيد. وبعد لكن، scandir
أو is_readable
يفشل بأسماء قصيرة جدا. وبعد الحل لاستخدام هذه الوظائف هو إعادة تشغيل أمر DIR بشكل متكرر.
للحصول على معلومات من ملف TXT، يمكنك استخدام تعبير أو مجموعة منتظمة، وتخلص من الخطوط الخمسة الأولى وآخرين. علي سبيل المثال:
for($k=6;$k<(count($array)-2);$k++) ...