การแก้ปัญหาภาษาไทย แสดงผลไม่ถูกต้อง ใน MySQL 4.1.x

การแก้ปัญหาภาษาไทย แสดงผลไม่ถูกต้อง ใน MySQL 4.1.x

บทความนี้ เริ่มต้นมาจากที่ ผมต้องเข้าไปแก้ไขสคริปต่างๆ มากมาย ที่จำเป็นต้องใช้ฐานข้อมูล MySQL เวอร์ชั่น 4.1.x ครับ เหตุที่ต้องเข้าไปแก้ ทั้งนี้เนื่องมาจากว่า ฐานข้อมูลเวอร์ชั่น 4.1.x เนี่ย มันจะมีการเพิ่มส่วนของ charset เข้ามาในระบบฐานข้อมูลด้วย ซึ่งเพิ่มความสะดวกในสคริปต่างๆในอนาคต เป็นอย่างมาก เพราะว่า เขียนโค้ดชุดเดียว แต่จะสามารถทำงานได้ทุกภาษาเลย

แต่ประเด็นที่เป็นปัญหาก็คือการ backup ฐานข้อมูลจากเวอร์ชั่นเก่า มาเข้าเวอร์ชั่น 4.1.x นี่สิ คือปัญหาใหญ่ ทั้งๆที่ host ก็ตั้งค่าให้คล้ายระบบเดิมมากที่สุดแล้ว(นั่นคือตั้งค่า charset ให้เป็น TIS-620 ทั้งหมด) แต่ก็ยังไม่วาย มีปัญหาเรื่องภาษาไทยอยู่ดี (ตอนนี้อาจจะมองว่ามันเป็นปัญหา แต่มองการณ์ไกล แล้วพบว่ามันคือความสะดวก หากเราเข้าใจที่จะใช้งาน)

ดังนั้น วันนี้จะมาบอกวิธีแก้ไขกัน สำหรับวิธีแก้ไข ก็ง่ายนิดเดียว แค่บรรทัดเดียวก็เสร็จ นั่นคือการเพิ่มโค้ด ด้านล่างนี้เข้าไปที่หลังคำสั่ง mysql_connect นั่นเอง

mysql_query("SET NAMES 'tis620' ");

เพียงแค่นี้ ที่ทุกจุดที่มีการ mysql_connect เติมอันนี้เข้าไปด้านหลัง ภาษาไทย ก็จะกลับมาเป็นปรกติ แต่ทั้งนี้ทั้งนั้น ต้องตรวจสอบให้ดีก่อน ว่าเนื้อหาในฐานข้อมูล ไม่ได้เป็น ??????? ไปแล้ว เพราะว่าถ้าในฐานข้อมูลมันเป็น ????? การเรียกออกมาก็ ไม่มีค่าอะไรอยู่ดี เพราะมันก็เรียกแต่ ????? ออกมาแสดงนั่นเอง

และไหนๆก็พูดเรื่องนี้ อย่างที่บอกว่า ได้แก้โค้ด มาหลายสคริปมากๆ ก็จะไล่ทีละ script

PHPBB ไฟล์ที่ต้องทำการแก้ไขก็คือ mysql.php และ mysql4.php ที่อยู่ในแฟ้ม db นั่นเอง โดยที่ให้เติม mysql_query("SET NAMES 'tis620' "); เข้าไป หลังจากบรรทัดที่มีการสั่ง connect เช่น

$this->db_connect_id = ($this->persistency) ? mysql_pconnect($this->server, $this->user, $this->password) : mysql_connect($this->server, $this->user, $this->password);
mysql_query("SET NAMES 'tis620' ");

อันนี้เอามาจากไฟล์ mysql4.php ครับ

ต่อมา คือ mambo ตัวนี้แก้ง่ายนิดเดียว ลักษณะเดียวกัน คือใส่เอาไว้หลังจากบรรทัดที่มีการ connect นั่นเองโดยให้แก้ไฟล์ที่ชื่อ database.php อยู่ในแฟ้ม include และที่ต้องเพิ่มเติมอีกจุดคือ หลังจากบรรทัด

$this->_table_prefix = $table_prefix;
$this->_ticker = 0;
$this->_log = array();
mysql_query("SET NAMES 'tis620' ");

ก็เติมเข้าไปตามตัวอย่างที่ให้ด้วยเช่นกัน ไฟล์เดียวจบ ใช้งานได้ต่อ

ตัวต่อมา IPB สำหรับเวอร์ชั่นที่ผม ได้แก้ไขมาคือ 2.1.4 นะครับ แต่เวอร์ชั่นอื่นไม่น่าจะต่างกันเท่าไร ที่เพิ่มเข้าไปคือ บรรทัดที่ 300ของไฟล์ ipsclass.php ในแฟ้ม sources โดยมีเนื้อหาว่า

//-----------------------------------------
// Make a safe query string
//-----------------------------------------
mysql_query("SET NAMES 'tis620' ");
$this->query_string_safe = str_replace( '&', '&', $this->parse_clean_value( urldecode($_SERVER['QUERY_STRING'] ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING') ) ) );

สีน้ำเงินคือที่เพิ่มเข้าไปครับ แล้วเซฟก็จะใช้งานได้ทันที และที่ไฟล์ index.php บรรทัดที่84

$ipsclass->init_db_connection();
mysql_query("SET NAMES 'tis620' ");

แต่สำหรับ IPB เวอร์ชั่น 1.1.2 แก้ที่ไฟล์ mySQL.php ใน sources/Drivers/ นะครับ บรรทัดที่ 66 ครับ

}
mysql_query("SET NAMES 'tis620' ");
if ( !mysql_select_db($this->obj['sql_database'], $this->connection_id) )

สำหรับ SMF เวอร์ชั่นที่ทดสอบคือ 1.0.7 นะครับ แก้ที่ไฟล์ index.php เลยครับ บรรทัดที่ 67

else
$db_connection = @mysql_pconnect($db_server, $db_user, $db_passwd);

mysql_query("SET NAMES 'tis620' ");
// Show an error if the connection couldn't be made.

สำหรับ XOOPS เวอร์ชั่นที่ทดสอบคือ 2.0.14 แก้ไขที่ไฟล์ mysqldatabase.php ที่เก็บอยู่ในแฟ้ม class/database บรรทัดที่ 79 ของเดิมคือ

$this->conn = @mysql_connect(XOOPS_DB_HOST, XOOPS_DB_USER, XOOPS_DB_PASS);
}

if (!$this->conn) {
$this->logger->addQuery('', $this->error(), $this->errno());

แก้ใหม่เป็น

$this->conn = @mysql_connect(XOOPS_DB_HOST, XOOPS_DB_USER, XOOPS_DB_PASS);
}
mysql_query("SET NAMES 'tis620' ");
if (!$this->conn) {
$this->logger->addQuery('', $this->error(), $this->errno());

สำหรับ OSCOMMERCE แก้2จุด 1.ไฟล์ที่แก้ไขคือ application_top.php ในแฟ้ม include และ 2.ไฟล์ที่แก้ไขคือ application_top.php ในแฟ้ม admin/include แก้บรรทัดที่ 66 ของเดิมคือ

// make a connection to the database... now
tep_db_connect() or die('Unable to connect to database server!');

แก้ใหม่เป็น

// make a connection to the database... now
tep_db_connect() or die('Unable to connect to database server!');
mysql_query("SET NAMES 'tis620' ");

?

สรุปหลักการก็คือเมื่อมีการ connect mysql ที่มีการรับส่งภาษาไทยเมื่อไร ให้นำ TAG
mysql_query("SET NAMES 'tis620' "); ไปวางไว้หลังบรรทัดคำสั่ง mysql_connect หรือ mysql_pconnect ทันทีครับ ปัญหาเรื่องภาษาไทย กับ MySQL เวอร์ชั่น 4.1.X ก็จะหมดไปทันทีครับ แต่ก็ต้องไม่ลืมที่จะต้องตั้ง charset ต่างๆของฐานข้อมูลให้เป็น TIS620 ด้วยนะครับ ตรวจสอบลึกเข้าไปถึงในตารางด้วย ว่า charset ของแต่ละตารางเป็น TIS620 ด้วยหรือไม่ --- สุดท้าย สคริปใดสามารถใช้งาน UTF-8 ได้ แนะนำให้ใช้ทันที เพราะจะทำให้ไม่ต้องแก้ tag ดังกล่าวข้างต้นที่กล่าวมาทั้งหมดครับ เพราะสามารถใช้งานในภาษาไทยได้ครับ ซึ่งสคริป ที่รองรับ UTF-8 ส่วนใหญ่จะเป็นสคริปที่ใหม่ๆครับ

จุดที่น่าให้ความสนใจในตอนนี้ นั่นก็คือการหาคำสั่งดังกล่าวให้เจอน่ะครับ หากมีการใช้สคริปอื่นๆที่ไม่ใช่ตามตัวอย่างที่กล่าวมาข้างต้น แต่หลักการค้นหาคำสั่ง connect ก็ไม่ยากครับ พยายามไล่ไฟล์ที่เรียกเข้ามาดู จะมีเทคนิคการเปิดคือ ชื่อไฟล์จะเป็นชื่อประมาณว่า mysql db database connect หรืออะไรที่ไกล้เคียงแบบนี้ครับ (แต่ไม่จำเป็นเสมอไป) พอเราลองเปิดแล้วก็พิมพ์คำค้นหาคำว่า connect เลยครับ เพื่อความรวดเร็ว

หรือใช้โปรแกรมพวก text editor เพื่อ find in files เลยก็ได้ เพื่อความรวดเร็วครับ

Create: Modify : 2007-02-18 07:00:00 Read : 32056 URL :