ดีบัก EntityFieldQuery หรือไม่


27

ฉันมีโมดูลที่ทำงานผิดปกติ EFQ กำลังรักษาผลที่ไม่คาดคิดไว้ แต่ฉันไม่สามารถเห็นสาเหตุได้เพียงแค่ดูรหัส มีdpq ()เทียบเท่ากับ EFQ หรือไม่ วิธีอื่นในการดีบั๊กหรือไม่


คำถามที่คล้ายกัน: drupal.stackexchange.com/questions/33473/… . คุณสามารถส่งแบบสอบถามวัตถุไปยังสตริงเพื่อตรวจสอบเพื่อดูว่า SQL ให้เบาะแสใด ๆ ?
ไคลฟ์

1
คำแนะนำที่ดีเยี่ยม: ข้อผิดพลาดร้ายแรงที่สามารถกู้คืนได้: วัตถุของคลาส EntityFieldQuery ไม่สามารถแปลงเป็นสตริงได้ :(
Letharion

คำตอบ:


36

เป็นแฮ็กเล็กน้อย แต่คุณสามารถเพิ่มแท็กให้กับสิ่งที่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 เป็นระบบจัดเก็บข้อมูลเท่านั้น


ฟังดูดีในทางทฤษฎี แต่สิ่งที่เกี่ยวกับความคิดเห็นเกี่ยวกับคำถาม? EFQ ไม่ได้ใช้ __toString ()?
Letharion

4
ตามเวลาที่ได้รับhook_query_alter()การค้นหาไม่ได้EntityFieldQueryอีกต่อไปมันถูกแปลงเป็นมาตรฐานdb_select()ดังนั้นใช้__tostring()งานได้ดี :) เนื่องจากการทำงานนี้ฉันได้ใช้มันค่อนข้างมากและใช้งานได้ดี
Clive

hook_query_alter()ยืนยันว่าหล่อสตริงทำงานครั้งเดียวแบบสอบถามได้รับการ
jhedstrom

ในการดูอาร์กิวเมนต์ queryos (": entity_type" ในตัวอย่างด้านบน) คุณสามารถใช้ dpm ($ query-> arguments ());
sanzante

13

แทนที่จะกลิ้ง hook_query_alter () ของคุณเองคุณสามารถปล่อยให้โมดูลDevelทำการยกของหนักโดยเพิ่มdebugแท็ก:

$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');
  ->addTag('debug')
  ->execute();

นี้จะพิมพ์แบบสอบถามไปยังหน้าจอเช่นเดียวdpq()หากว่า


4

การเพิ่มคำตอบ @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();

ไม่ใช่แนวปฏิบัติที่ดีในการติดตั้งโมดูลสำหรับโค้ดสองสามบรรทัด นั่นคือเหตุผลที่ฉันเลือกใช้โซลูชันดังกล่าว


2

หากคุณดาวน์โหลดรุ่น 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()ที่ทริกเกอร์


วิธีแก้ปัญหาอื่นที่ดีในการพัฒนา ไม่พบโมดูลนั้นโดยตรงเกินเพราะพวกเขาลบบล็อกโมดูลที่เกี่ยวข้องซึ่งมี earliar
kiranking

1

คุณสามารถพยายามที่จะแก้ปัญหาผ่านทาง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)


0

เพิ่มฟังก์ชั่นนี้ลงในโมดูลของคุณ จากนั้นเพิ่มแท็ก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);
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.