گیک فارسی

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

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

نویسنده:
6 سپتامبر 16

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

موفق باشین.

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

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

نشانی ایمیل شما منتشر نخواهد شد.