اذا كنت تستخدم ترميز أسكي ASCII سابقا لحفظ بياناتك على القاعدة، وقمت بتحويل بنية القاعدة إلى UTF8، فإن السيرفر سيبدأ بقراءة البيانات السابقة بترميز غير صحيح
الحل
ان تقوم بتحويل ترميز البيانات السابقة إلى UTF8
هذا سيحتاج إلى عمل برمجي من نوع ما
أعطيك مثال لحل مقترح
اقرأ البيانات من القاعدة بالترميز الأساسي Latin1، وقم بحفظها في مصفوفات
ثم قم بتحويل ترميز الاتصال بالقاعدة إلى UTF8
كود:
mysql_query("SET NAMES 'utf8' ");
ثم تقوم بعمل update للسجلات بالبيانات نفسها بالترميز الجديد
هذا حل مقترح، قم بتجربته
__________________ الخدمات البرمجية
تعديلات برمجية - تطوير برمجيات جاهزة - صيانة قواعد بيانات
برمجة خاصة (الأولوية للأفكار الجديدة والخاصة)
echo "Altered field {$name} on {$tab} from type {$type}\n"; } else if (!strcasecmp($type, "CHAR")) { mysql_query("ALTER TABLE {$tab} MODIFY {$name} BINARY(1)"); MysqlError(); mysql_query("ALTER TABLE {$tab} MODIFY {$name} VARCHAR(1) CHARACTER SET {$target_charset}"); MysqlError(); $set = true;
echo "Altered field {$name} on {$tab} from type {$type}\n"; } else if (!strcasecmp($type, "TINYTEXT")) { mysql_query("ALTER TABLE {$tab} MODIFY {$name} TINYBLOB"); MysqlError(); mysql_query("ALTER TABLE {$tab} MODIFY {$name} TINYTEXT CHARACTER SET {$target_charset}"); MysqlError(); $set = true;
echo "Altered field {$name} on {$tab} from type {$type}\n"; } else if (!strcasecmp($type, "MEDIUMTEXT")) { mysql_query("ALTER TABLE {$tab} MODIFY {$name} MEDIUMBLOB"); MysqlError(); mysql_query("ALTER TABLE {$tab} MODIFY {$name} MEDIUMTEXT CHARACTER SET {$target_charset}"); MysqlError(); $set = true;
echo "Altered field {$name} on {$tab} from type {$type}\n"; } else if (!strcasecmp($type, "LONGTEXT")) { mysql_query("ALTER TABLE {$tab} MODIFY {$name} LONGBLOB"); MysqlError(); mysql_query("ALTER TABLE {$tab} MODIFY {$name} LONGTEXT CHARACTER SET {$target_charset}"); MysqlError(); $set = true;
echo "Altered field {$name} on {$tab} from type {$type}\n"; } else if (!strcasecmp($type, "TEXT")) { mysql_query("ALTER TABLE {$tab} MODIFY {$name} BLOB"); MysqlError(); mysql_query("ALTER TABLE {$tab} MODIFY {$name} TEXT CHARACTER SET {$target_charset}"); MysqlError(); $set = true;
echo "Altered field {$name} on {$tab} from type {$type}\n"; }
if ($set) mysql_query("ALTER TABLE {$tab} MODIFY {$name} COLLATE {$target_collate}"); }
// re-build indicies.. foreach ($indicies as $index) { if ($index["unique"]) { mysql_query("CREATE UNIQUE INDEX {$index["name"]} ON {$tab} ({$index["col"]})"); MysqlError(); } else { mysql_query("CREATE INDEX {$index["name"]} ON {$tab} ({$index["col"]})"); MysqlError(); }
echo "Created index {$index["name"]} on {$tab}. Unique: {$index["unique"]}\n"; }
// set default collate mysql_query("ALTER TABLE {$tab} DEFAULT CHARACTER SET {$target_charset} COLLATE {$target_collate}"); }
// set database charset mysql_query("ALTER DATABASE {$db} DEFAULT CHARACTER SET {$target_charset} COLLATE {$target_collate}");
mysql_close($conn); echo "</pre>";
لا تنسي إضافة لملف الإتصال عندك
كود PHP:
@mysql_set_charset('utf8'); @mysql_query('SET NAMES utf8'); @mysql_query('SET CHARACTER SET utf8'); @mysql_query('SET COLLATION_CONNECTION="utf8_general_ci"');
بالطبع يبقي عمل النسخ لقاعدة البيانات والزرع مرة اخري
إستعمل هذا السكريبت الممتاز في نسخ قواعد البيانات وإعادة الزرع عند الحاجة من هنا
أعطيك مثال لحل مقترح
اقرأ البيانات من القاعدة بالترميز الأساسي Latin1، وقم بحفظها في مصفوفات
ثم قم بتحويل ترميز الاتصال بالقاعدة إلى UTF8
تفضل هذه هي الطريقة الصحيحة اجلب البيانات حولها لutf ب iconv
ثم اعد زرعاتها
إليك سكربيتك مع التعديل
كود PHP:
<?php header('(anti-spam-content-type:) text/html; charset=utf-8' ); $sql_text=""; $sql="select * from tab1 order by id DESC"; $res=mysql_query($sql); mysql_query("SET NAMES 'utf8'"); mysql_query('SET CHARACTER SET utf8');
<?php header('(anti-spam-(anti-spam-content-type:)) text/html; charset=utf-8' ); include ("config.php"); $sql_text=""; $sql="select * from tab1 order by id DESC"; $res=mysql_query($sql); mysql_query("SET NAMES 'utf8'"); mysql_query('SET CHARACTER SET utf8');
كتبت رد وقمت بتعديله بعد مشاهدة الملفات لان ترميز الملفات utf8
جدول tab1 لديك بترميز latin1 وهو الواضح من الملف المرفق
ENGINE=MyISAM DEFAULT CHARSET=latin1
قم بتعديلها الى
ENGINE=MyISAM DEFAULT CHARSET=utf8
وقم بالتجربة مرة اخرى
__________________ قل اللهم مالك المُلك تؤتي الملك من تشاء وتنزع الملك ممن تشاء وتعز من تشاء وتذل من تشاء بيدك الخير انك على كل شىء قدير
آخر تعديل بواسطة مهندس مصرى في 15-04-2011 الساعة 09:31 PM.
او قم بتعديل ترميز الملف نفسه الى utf-8 ولا تكتفي باضافة هيدر utf-8
اما عن نقل البيانات فهذا يستلزم منك اجراء تعديل على كل البيانات الموجودة داخل قاعدة البيانات ..
قم بانشاء قاعدة بيانات جديدة بترميز utf8 بنفس الجداول والحقول الموجودة في قاعدة البيانات القديمة ولا تضع بها اي داتا (وقم بمراعاة ان يكون الجداول والحقول وقاعدة البيانات جميعا بترميز utf8).
قم بعمل اسكربت بسيط يقوم بعمل اتصالين في نفس الملف اتصال على قاعدة البيانات القديمة واتصال على قاعدة البيانات الجديدة على سبيل المثال سنسمي الاتصال الاول $conn1 والاتصال الثاني $conn2 .
لو كان لديك مثلا جدول tab1 والحقل title ساوضح كيف يتم اجراء تعديل عليه ونقله بترميز جديد..
عند استخدام iconv فالترميز الصحيح الذي يجب استخدامه داخل الامر iconv هو cp1256 وليس windows-1256.
هناك حل آخر وهو ان تقوم بتجربة حل السكربت الذي وضعه zamile28 .. ولم اجربه من قبل لكن اطلعت الان على شفيرته البرمجية فوجدت انه غير آمن لانه يقوم بتعديل البيانات في نفس القاعدة لذلك قد يحدث خطأ معين اثناء التعديل فبالتالي تحدث لديك مشاكل في قاعدة البيانات لأنه سيكون هناك بعض الداتا محولة والباقي غير محول .. لذلك اذا اردت استخدامه قم بعمل نسخة احتياطية اولاً من قاعدة البيانات.
__________________ قل اللهم مالك المُلك تؤتي الملك من تشاء وتنزع الملك ممن تشاء وتعز من تشاء وتذل من تشاء بيدك الخير انك على كل شىء قدير
اريد ان اجرب حتى اصل الى الحل بمساعدتكم ان شاء الله.
فقط اصبروا علي
وان فشلت فسارسل لك اخي زميل القاعدة كلها لتحويلها برمجيا (لان هذا امر تحويل البيانات ينفع عند ترقية نسخة ما)
اسئلة عند الاسترجاع :
1 - هل يجب ان تكون جميع ملفات php محفوظة بـ UTF8 Wihtout BOM ؟
2 - هل هيدر الملفات يجب ان يكون UTF8 وليس windows-1256 ؟
3 - هل يجب زيادة السطور :
كود PHP:
@mysql_set_charset('utf8'); @mysql_query('SET NAMES utf8'); @mysql_query('SET CHARACTER SET utf8'); @mysql_query('SET COLLATION_CONNECTION="utf8_general_ci"');
في ملف الاتصال من البداية ولا خوف بان يؤثر ذلك كله عند استرجاع البيانات بترميز latin1 من القاعدة ؟
4 - هل حفظ ناتج البيانات المسترجعة في ملف update.sql فكرة جيدة ؟ وكيف نضمن انه يتم حفظه تحت ترميز UTF8 Without BOM ولا "تتخربش" البيانات ؟
UPDATE `tab2` SET `name` ='عادل', `country`='سوريا', `town`='حماة ' where `id` = '8' ; UPDATE `tab2` SET `name` ='علي', `country`='العراق', `town`='البغدادية ' where `id` = '7' ; UPDATE `tab2` SET `name` ='فيصل', `country`='السعودية', `town`='الرياض ' where `id` = '6' ; UPDATE `tab2` SET `name` ='احمد', `country`='مصر', `town`='بور سعيد ' where `id` = '5' ; UPDATE `tab2` SET `name` ='عمر', `country`='العراق', `town`='كربلاء ' where `id` = '4' ;
اما نزعت سلاش التعليقات من امام السطور :
كود PHP:
mysql_set_charset($Charset,$link); mysql_query("SET NAMES $Charset;", $link) or die ('Erreur de connexion au serveur: '.mysql_error()); mysql_set_charset("utf8");
فسيصبح ملف update.sql غير مقروء هكذا :
كود PHP:
UPDATE `tab2` SET `name` ='ط£ع‘ط£â€،ط£عˆط£طŒ', `country`='ط£â€œط£آ¦ط£â€کط£آط£â€،', `town`='ط£ع†ط£آ£ط£â€،ط£â€° ' where `id` = '8' ; UPDATE `tab2` SET `name` ='ط£ع‘ط£طŒط£آ', `country`='ط£â€،ط£طŒط£ع‘ط£â€کط£â€،ط£â€چ', `town`='ط£â€،ط£طŒط£ث†ط£â€؛ط£عˆط£â€،ط£عˆط£آط£â€° ' where `id` = '7' ; UPDATE `tab2` SET `name` ='ط£â€Œط£آط£â€¢ط£طŒ', `country`='ط£â€،ط£طŒط£â€œط£ع‘ط£آ¦ط£عˆط£آط£â€°', `town`='ط£â€،ط£طŒط£â€کط£آط£â€،ط£â€“ ' where `id` = '6' ; UPDATE `tab2` SET `name` ='ط£â€،ط£ع†ط£آ£ط£عˆ', `country`='ط£آ£ط£â€¢ط£â€ک', `town`='ط£ث†ط£آ¦ط£â€ک ط£â€œط£ع‘ط£آط£عˆ ' where `id` = '5' ; UPDATE `tab2` SET `name` ='ط£ع‘ط£آ£ط£â€ک', `country`='ط£â€،ط£طŒط£ع‘ط£â€کط£â€،ط£â€چ', `town`='ط£ع؛ط£â€کط£ث†ط£طŒط£â€،ط£ظ¾ ' where `id` = '4' ;
ولكن هذه السطور الا احتاجها في عملية الادراج بعد تحويل القاعدة الى ترميز UTF8 ؟
في هذه الحالة وجب ايجاد ملفي اتصال :
1 - الاول خاص بالاسترجاع عندما تكون القاعدة بترميز latin1.
2 - الثاني خاص بالادراج عندما تصبح القاعدة بترميز utf8.
ملف get_datas.php المستعمل (محفوظ بصيغة UTF8 without BOM)
كود PHP:
<?php header('(anti-spam-(anti-spam-content-type:)) text/html; charset=utf-8' ); include ("config.php"); $sql_text=""; $sql="select * from tab2 order by id DESC"; $res=mysql_query($sql); mysql_query("SET NAMES 'utf8'"); mysql_query('SET CHARACTER SET utf8');