แก้ปัญหา meta_compare ทำงานไม่ถูกต้องใน WordPress
ใน WordPress เราสามารถสั่ง Query โพสต์ออกมาตามค่าใน custom field ได้ (หรือชื่อในเชิงเทคนิคคือ Post Meta) ด้วยการเพิ่มอาร์กิวเมนต์ meta_query ลงไปในขั้นตอนการคิวรี่ อย่างนี้
$args = array( 'post_type' => "mytype", 'meta_query' => array( array( 'key' => "mymeta", 'value' => "myvalue", 'compare' => "=" ) ) ); $myQuery = new WP_Query($args);
ซึ่งตามตัวอย่างข้างบน จะเป็นการสั่งคิวรี่โพสต์จากโพสต์ไทป์ mytype โดยจะดึงจากโพสต์ที่มีค่า mymeta เท่ากับ myvalue
การคิวรี่นี้จะไม่เกิดปัญหาใดๆ ตราบใดที่เป็นการคิวรี่ตาม string ธรรมดา แต่เมื่อใดก็ตามที่ต้องการเปรียบเทียบในลักษณะอื่นที่นอกเหนือจากข้อความธรรมดา (เช่นตัวเลข หรือวันที่) การคิวรี่ด้วย meta compare ธรรมดาแบบนี้จะมีปัญหาทันที เนื่องจากตัว WordPress จะมอง custom field เป็น string ธรรมดาๆ เป็นค่าปริยาย
อย่างไรก็ตาม ตั้งแต่ WordPress 3.1 เป็นต้นมา ก็มีการแก้ไขข้อบกพร่องนี้ ด้วยการเพิ่มอาร์กิวเมนต์ “type” เข้ามาครับ เพื่อเป็นการสั่งให้ Cast ค่าที่จะเอาไปเทียบนี้ ให้เป็นแบบอื่นนอกจาก String ธรรมดา วิธีใช้ก็เพียงแค่ประกาศ “type” เพิ่มเข้าไปใน meta_query อย่างนี้
$args = array( 'post_type' => "mytype", 'meta_query' => array( array( 'key' => "mymeta", 'value' => "10", 'compare' => "<=", 'type' => 'numeric' ) ) ); $myQuery = new WP_Query($args);
และ WordPress ก็จะจัดการ Cast ค่านี้เสียใหม่ ก่อนจะนำไปคิวรี่หาจากฐานข้อมูลครับ
สำหรับค่าต่างๆ ของ type ที่สามารถใช้ได้ มีดังนี้
- ‘NUMERIC’ สำหรับตัวเลข
- ‘BINARY’ สำหรับข้อมูลแบบ Binary
- ‘CHAR’ สำหรับข้อมูลตัวอักษร (เป็นค่าปริยาย)
- ‘DATE’ สำหรับวันที่
- ‘DATETIME’ สำหรับวันที่พร้อมเวลา
- ‘DECIMAL’ สำหรับตัวเลข
- ‘SIGNED’ สำหรับตัวเลข นับติดลบด้วย
- ‘TIME’ สำหรับเวลา
- ‘UNSIGNED’ สำหรับตัวเลข ไม่นับติดลบ
อันที่จริงมันก็คือค่าที่เอาไปใส่่ในฟังก์ชัน Cast ของ MySQL นั่นแหละครับ
แบบนี้น่ะครับ แบบโค้ดที่คุณโพสด้านบน ที่ผมถามไว้ในเฟส ที่ส่งข้อความเข้าไปน่ะครับ