ฉันมีโมดูลที่ทำงานผิดปกติ EFQ กำลังรักษาผลที่ไม่คาดคิดไว้ แต่ฉันไม่สามารถเห็นสาเหตุได้เพียงแค่ดูรหัส มีdpq ()เทียบเท่ากับ EFQ หรือไม่ วิธีอื่นในการดีบั๊กหรือไม่
ฉันมีโมดูลที่ทำงานผิดปกติ EFQ กำลังรักษาผลที่ไม่คาดคิดไว้ แต่ฉันไม่สามารถเห็นสาเหตุได้เพียงแค่ดูรหัส มีdpq ()เทียบเท่ากับ EFQ หรือไม่ วิธีอื่นในการดีบั๊กหรือไม่
คำตอบ:
เป็นแฮ็กเล็กน้อย แต่คุณสามารถเพิ่มแท็กให้กับสิ่งที่EntityFieldQuery
คุณสนใจในการพิมพ์ข้อความค้นหาจากนั้นนำhook_query_alter()
ไปใช้เพื่อดักจับมันเมื่อเป็นมาตรฐานSelectQuery
แล้วส่งไปยังสตริงสำหรับการดีบัก:
function MYMODULE_query_alter($query) {
if ($query->hasTag('efq_debug')) {
dpm((string)$query);
}
}
$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node')
->addTag('efq_debug')
->execute();
มันเป็นเรื่องของการแฮ็ค แต่ทำเคล็ดลับได้ ผลลัพธ์สำหรับข้างต้นคือ:
SELECT node.nid AS entity_id, node.vid AS revision_id, node.type AS bundle, :entity_type
AS entity_type
FROM {node} node
สันนิษฐานว่าสิ่งนี้จะใช้ได้เมื่อใช้ MySQL เป็นระบบจัดเก็บข้อมูลเท่านั้น
hook_query_alter()
การค้นหาไม่ได้EntityFieldQuery
อีกต่อไปมันถูกแปลงเป็นมาตรฐานdb_select()
ดังนั้นใช้__tostring()
งานได้ดี :) เนื่องจากการทำงานนี้ฉันได้ใช้มันค่อนข้างมากและใช้งานได้ดี
hook_query_alter()
ยืนยันว่าหล่อสตริงทำงานครั้งเดียวแบบสอบถามได้รับการ
แทนที่จะกลิ้ง hook_query_alter () ของคุณเองคุณสามารถปล่อยให้โมดูลDevelทำการยกของหนักโดยเพิ่มdebug
แท็ก:
$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');
->addTag('debug')
->execute();
นี้จะพิมพ์แบบสอบถามไปยังหน้าจอเช่นเดียวdpq()
หากว่า
การเพิ่มคำตอบ @Clive ซึ่งโดยทั่วไปจะพิมพ์คิวรีที่มีตัวยึดตำแหน่งไม่พร้อมกับค่า หากต้องการพิมพ์ค่าด้วยแบบสอบถามให้ใช้รหัสต่อไปนี้ภายใต้ hook_query_alter
function hook_query_alter($query) {
if ($query->hasTag('debug')) {
$sql = (string)$query;
$connection = Database::getConnection();
foreach ((array) $query->arguments() as $key => $val) {
$quoted[$key] = $connection->quote($val);
}
$sql = strtr($sql, $quoted);
dpm($sql);
}
}
$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');
->addTag('debug');
->execute();
ไม่ใช่แนวปฏิบัติที่ดีในการติดตั้งโมดูลสำหรับโค้ดสองสามบรรทัด นั่นคือเหตุผลที่ฉันเลือกใช้โซลูชันดังกล่าว
หากคุณดาวน์โหลดรุ่น dev ของNice DPQ (หรืออะไรก็ได้ => 1.1) คุณสามารถทำได้ดังนี้:
$user_query = new EntityFieldQuery();
$user_query->entityCondition('entity_type','user');
$user_query->addTag('nicedpq');
$user_result = $user_query->execute();
และคุณจะได้รับแบบสอบถาม dpm'ed อย่าง :) ส่วนที่สำคัญในรหัสข้างต้นเป็นaddTag ( 'nicedpq') - dpm()
ที่ทริกเกอร์
คุณสามารถพยายามที่จะแก้ปัญหาผ่านทางXDebug เมื่อติดตั้งเสร็จแล้วให้ทำxdebug_start_trace()
ก่อนโค้ดและxdebug_stop_trace()
หลังจากนั้นคุณจะมีบันทึกการติดตามที่ชัดเจนว่าอะไรที่ถูกเรียกใช้และที่ใด
นอกจากนี้คุณสามารถเปิดใช้งานตัวบันทึกแบบสอบถามในการกำหนดค่า MySQL
อีกวิธีคือใช้ strace / truss / dtruss เช่น debuggers
ตัวอย่างการใช้ dtruss:
แบบสอบถามทั้งหมด
sudo dtruss -t read -n mysqld
ข้อความค้นหาเฉพาะ
sudo dtruss -t read -n mysqld 2>&1 | grep SPECIFIC_TEXT
โปรดทราบว่าdtruss
เป็นเพียงสคริปต์ที่ใช้ DTrace ดังนั้นคุณอาจพิจารณาใช้งานโพรบแบบคงที่โดยตรงของPHP DTraceหรือDTracing MySQLโดยการเขียนสคริปต์ของคุณเอง
อ่านเพิ่มเติม: การดีบักขั้นสูงของ Drupal core โดยใช้บรรทัดคำสั่ง (strace & tcpdump)
เพิ่มฟังก์ชั่นนี้ลงในโมดูลของคุณ จากนั้นเพิ่มแท็กdebug
ใน EFQ ใด ๆ ต้องเปิดใช้งานโมดูล Devel เพื่อพิมพ์แบบสอบถาม
/**
* Implements hook_query_TAG_alter().
*
* Add the tag 'debug' to any EFQ and this will print the query to the messages.
*
* @param \QueryAlterableInterface $query
*/
function MYMODULE_query_debug_alter(QueryAlterableInterface $query) {
if (function_exists('dpq') && !$query->hasTag('debug-semaphore')) {
$query->addTag('debug-semaphore');
dpq($query);
}
}