گیک فارسی

نوشته های یک گیک فارسی از فعالیت ها ،‌ علاقه مندی ها و نقد هایش

مشکل در نمایش اطلاعات فارسی به صورت علامت سوال از پایگاه داده MySQL در PHP

26 دیدگاه‌ها

شاید یکی از پرشمارترین سؤالاتی که از طرف تازه کار ها و گاهی اوقات حتی باتجربه های 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>

موفق باشین.



برچسب‌ها:

  1. ب گفت:

    دستت درد نکنه. 5 سال پی اچ پی کد میزنم همیشه این مشکل و دارم

  2. علی رضا گفت:

    دمت گرم خیلی گشتم بالاخره این جا پیدا کردم

  3. میلاد گفت:

    دم شما گرررررم

  4. قادر گفت:

    واقعا دمت گرررررررررررررم
    من معمولا هیج جا تشکر نمیکنم چون همه کپی میکنن از یه جای دیگه. ولی یه نکته ای تو مطلبت هست که سه روزه همه سایتا رو زیر و رو کردم ولی پیدا نکردم
    ۵ – اگه از کتابخونه mysqli استفاده میکنید بعد از connect متد set_charset را صدا بزنید :
    اینجا یافتمش. خیییییییییییلییییییییی کرتییییییییییییییییییییم

  5. محمدحسن گفت:

    آقا واقعا ممنونم
    کلی گشتم تا اینجا مشکلم حل شد…
    خیلی مرتب و کامل نوشته بودید.

  6. حمید گفت:

    دمت گرم مشکلم حل شد 🙂

  7. سجاد گفت:

    عالی بود مرسی

  8. میم کاف گفت:

    واااااااااای عااالی داشتم ناامید میشدم:)))))))))خخخخ

  9. محمد گفت:

    عالی بود منم مشکلم اینجا حل شد . خدا خیرتون بده

  10. جواد گفت:

    دمت گرم مشکلم حل شد

  11. حسین گفت:

    خدا خیرتون بده .روش pdo رو هیچ جا پیدا نکرده بودم .خیلی ممنون

  12. amir گفت:

    دمت گرم هیچ سایتی مثل اینجا کامل نبود

  13. علیرضا گفت:

    مرسی از سایت عالیتون

  14. متین گفت:

    سلام ؛ خیلی جامع و کاربردی بود ؛ دست شما درد نکنه.

  15. alikhan گفت:

    سلام تشکر از مطالب ارزشمندتان. هر سایتی رفتم مشکلم حل نشد تا به این سایت برخوردم.

  16. حمید گفت:

    آقا بشدت دمت گرم 🙂 بالای 5 6 ساعت گشتم و از آخر اینجا به نتیجه رسیدم

  17. دمت گرم عالی بود

  18. وحیده گفت:

    سلام. راه گشا بود. ممنون

  19. عباس گفت:

    ممنون از مطلب جامع و کاملتون راجب این مسئله

  20. Ram گفت:

    آقا یه دنیا ممنون هزار تا سایت ایرانیو و خارجیو گشتم آخرم فقط سایت شما بود که جواب منو داد بخصوص اون قسمت که به روش pdo رو نوشتین.

  21. کاظم گفت:

    عالی بود. از بیشتر سایت ها امتحان کردم نشد. روش شما کارساز بود

  22. Hitroik گفت:

    بابا تو بمیلی بمولا ظرف کار تر ازتو ندیدم دمت گرمه

  23. حمید گفت:

    عالی عالی عالی

  24. یاسین گفت:

    به شدت دمت گرم
    کل سایت های معروف و بزرگ رو جستجو کردم ولی فقط چرت نوشته بودن ولی شما مشکل منو حل کردی
    خدا خیرت بده

  25. یاسین گفت:

    یک نکته عجیب
    من یک واکشی از دیتابیس کردم، روی لوکال هاست متن فارسی رو درست نشون میده ولی وقتی روی هاست همین عمل رو انجام میدم، حروف فارسی به صورت علامت سوال میشه
    اگه دلیلش رو میدونین که خوشحال میشم بدونم

    1. یونیک مدیر گفت:

      لوکال و ریموت هیچ فرقی نداره جز اینکه احتمالا شما ویندوز داری و ریموت لینوکس هست البته این هم فرق آنچنانی ایجاد نمیکنه! همین مراحل را برای ریموت بررسی کن. موردی غیر از اینها نمیتونه باشه.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *