شاید یکی از پرشمارترین سؤالاتی که از طرف تازه کار ها و گاهی اوقات حتی باتجربه های PHP کار باهاش مواجه شدم همین نمایش اطلاعات فارسی از پایگاه داده هست که عموما شاکی هستند اطلاعات را به فارسی در پایگاه ذخیره میکنند اما وقتی کد مربوط به نمایش را مینویسند همه متون به صورت علامت سؤال نمایش داده میشود.
از اونجا که غالباً هر کسی در بخشی از پروسه انجام کار مشکل داره من به ترتیب مراحل اطمینان از درستی انجام کار را در چند شماره توضیح میدم :
۱ – زمانی که پایگاه داده را روی سیستم خودتون نصب میکنید اطمینان حاصل کنید که در مراحل نصب ، پشتیبانی از utf8 را در تنظیمات mysql انجام میدین. روی هاست ها میشه ۹۹ درصد مطمئن بود که از utf8 روی mysql پشتیبانی میشه.
۲ – زمانی که جدول را ایجاد میکنید بهتره برای جلوگیری از مشکلات آتی و فارغ از اینکه Charset پیشفرض و Colltation پیشفرض در زمان نصب MySQL چی بوده خودتون جداول را با Charset از نوع utf8 و Collation از نوع utf8_persian_ci ایجاد کنید.
توجه: اگه این دو مورد خیلی براتون ملموس نیست اهمیتی نداره ! اگه توی phpmyadmin یا هر برنامه مدیریت پایگاه دادهای که استفاده میکنید میتونید فارسی بنویسین و ذخیره کنین و نمایش بگیرین پس کلاً با utf8 مشکل ندارین مگه جاهای خاص که ربطی به موضوع این پست نداره و اگه مشکل دارین با پشتیبانی شرکت میزبان وب خودتون تماس بگیرین.
۳ – حتماً اطمینان حاصل کنید که charset صفحه html را توی تگ meta برابر با utf8 قرار بدین :
در html4 و xhtml
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
در html5
<meta charset="UTF-8">
۴ – اگه از کتابخونه mysql توی php استفاده میکنید حتماً بعد از mysql_connect (دقیقاً بعدش نه اینکه بعد از select گرفتن این کار را انجام بدین !!!) mysql_set_charset را اجرا کنین :
$link = mysql_connect("server_ip_address","mysql_user_name","mysql_pass",true); mysql_set_charset('utf8',$link);
توجه: ممکنه خیلی جاها ببینید گفته باشن این دو query را بعد از connect اجرا کنین :
mysql_query("SET NAMES 'utf8'",$link); mysql_query("SET character_set_connection = 'utf8'",$link);
اما تابع mysql_set_charset بهتر و بهینه تره چون باعث میشه زمان استفاده از تابع mysql_real_escape_string که برای جلوگیری از حملات SQL Injection خیلی مهم هست کاراکتر های یونیکد به درستی escape بشن که در حالت پیشنهادی دوم این اتفاق نمیفته و شما در مقابل برخی حملات SQL Injection در خطر قرار میگیرین !
۵ – اگه از کتابخونه mysqli استفاده میکنید بعد از connect متد set_charset را صدا بزنید :
$db = new mysqli('server_ip_address', 'db-user', 'db-pass', 'db-name'); $db->set_charset("utf8");
۶ – اگه از کتابخونه pdo استفاده میکنید زمان connect باید charset را توی dsn مشخص کنید:
$link = new PDO("mysql:host=localhost;dbname=DB;charset=utf8");
توجه: کلاً بهتره کتابخونه mysql را بیخیال بشین چون دیگه توی نسخه های جدید php پشتیبانی نمیشه و کلاً حذف شده. اما در مورد mysqli و pdo خیلی سلیقهای هست که توصیه میکنم اگه از mysql استفاده میکنید و قصد جایگزینیش با mssql و پایگاه های دیگه را ندارید حتماً از mysqli استفاده کنید چون سریعتر از PDO هست و برای پایگاه داده mysql بهینه شده.
اگه همه موارد را درست رعایت کرده باشین هیچ مشکلی در نمایش و درج فارسی با پایگاه داده MySQL توی PHP نخواهید داشت. من در پایان هم یک نمونه کد جهت تست قرار میدم :
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>نمایش محتوای جدول</title> <style> body{ font-family:tahoma; font-size:12px; } </style> </head> <body> <?php $db = new mysqli('localhost', 'db-user', 'db-pass', 'db-name'); if($db->connect_errno > 0){ die('خطا در زمان اتصال به پایگاه داده [' . $db->connect_error . ']'); }else{ $db->set_charset("utf8"); $result = $db->query("select * from tbl_names"); echo "<table border='1' style='direction:rtl'>"; echo "<tr style='font-weight:bold;background-color:#ccc'>"; echo "<td>نام</td>"; echo "<td>نام خانوادگی</td>"; echo "<td>کد ملی</td>"; echo "</tr>"; while($row = $result->fetch_assoc()){ echo "<tr>"; echo "<td>{$row['fld_name']}</td>"; echo "<td>{$row['fld_family']}</td>"; echo "<td>{$row['fld_idnumber']}</td>"; echo "</tr>"; } echo "</table>"; $result->free(); $db->close(); } ?> </body> </html>
موفق باشین.
دستت درد نکنه. 5 سال پی اچ پی کد میزنم همیشه این مشکل و دارم
دمت گرم خیلی گشتم بالاخره این جا پیدا کردم
دم شما گرررررم
واقعا دمت گرررررررررررررم
من معمولا هیج جا تشکر نمیکنم چون همه کپی میکنن از یه جای دیگه. ولی یه نکته ای تو مطلبت هست که سه روزه همه سایتا رو زیر و رو کردم ولی پیدا نکردم
۵ – اگه از کتابخونه mysqli استفاده میکنید بعد از connect متد set_charset را صدا بزنید :
اینجا یافتمش. خیییییییییییلییییییییی کرتییییییییییییییییییییم
آقا واقعا ممنونم
کلی گشتم تا اینجا مشکلم حل شد…
خیلی مرتب و کامل نوشته بودید.
دمت گرم مشکلم حل شد 🙂
عالی بود مرسی
واااااااااای عااالی داشتم ناامید میشدم:)))))))))خخخخ
عالی بود منم مشکلم اینجا حل شد . خدا خیرتون بده
دمت گرم مشکلم حل شد
خدا خیرتون بده .روش pdo رو هیچ جا پیدا نکرده بودم .خیلی ممنون
دمت گرم هیچ سایتی مثل اینجا کامل نبود
مرسی از سایت عالیتون
سلام ؛ خیلی جامع و کاربردی بود ؛ دست شما درد نکنه.
سلام تشکر از مطالب ارزشمندتان. هر سایتی رفتم مشکلم حل نشد تا به این سایت برخوردم.
آقا بشدت دمت گرم 🙂 بالای 5 6 ساعت گشتم و از آخر اینجا به نتیجه رسیدم
دمت گرم عالی بود
سلام. راه گشا بود. ممنون
ممنون از مطلب جامع و کاملتون راجب این مسئله
آقا یه دنیا ممنون هزار تا سایت ایرانیو و خارجیو گشتم آخرم فقط سایت شما بود که جواب منو داد بخصوص اون قسمت که به روش pdo رو نوشتین.
عالی بود. از بیشتر سایت ها امتحان کردم نشد. روش شما کارساز بود
بابا تو بمیلی بمولا ظرف کار تر ازتو ندیدم دمت گرمه
عالی عالی عالی