วิธีปรับแต่งคลาส wpdb และเพิ่มวิธีการใหม่
เผยแพร่แล้ว: 2018-07-10เลเยอร์นามธรรมฐานข้อมูล WordPress หรือที่รู้จักกันทั่วไปว่า wpdb เป็นคลาสที่ใช้ ezSQL ที่รับผิดชอบในการโต้ตอบกับฐานข้อมูล คลาส wpdb เป็นแบบดรอปอิน ซึ่งเป็นชิ้นส่วนของโค้ด WP หลักที่สามารถแทนที่ด้วยโค้ดอื่นที่มีฟังก์ชันการทำงานที่คล้ายกันได้อย่างง่ายดาย (รายการดรอปอินล่าสุดมีอยู่ในการอ้างอิงโค้ด WP)
การแก้ไขคลาส #wpdb เริ่มต้นนั้นไม่ซับซ้อน คุณสามารถเพิ่ม ลบ หรือแก้ไขได้อย่างง่ายดายเพียงไม่กี่วิธี ไม่จำเป็นต้องเปลี่ยนทั้งชั้น #เวิร์ดเพรส
คลิกเพื่อทวีตนี่คือจุดที่เกิดความเข้าใจผิดครั้งใหญ่ ผู้คนรับรู้ "ถูกแทนที่" เช่นเดียวกับใน "เขียนคลาสฐานข้อมูลที่สมบูรณ์ของฉันเอง" โชคดีที่คุณไม่จำเป็นต้องเขียนคลาสฐานข้อมูลทั้งหมด คุณสามารถใช้คลาสที่มีอยู่และเพิ่ม ลบ หรือแก้ไขเฉพาะฟังก์ชันที่คุณต้องการ และนั่นคือสิ่งที่เรากำลังจะทำ
ทำไมต้องแก้ไขคลาส wpdb?
แน่นอน wpdb มีทุกสิ่งที่คุณต้องการ!? WP ทั้งหมดถูกสร้างขึ้นบนนั้น ในทางเทคนิคนั้นถูกต้อง โดยใช้ $wpdb->query()
คุณสามารถรันคำสั่ง SQL ใดๆ ก็ได้ แต่ด้วยตรรกะนั้น เราจะไม่มีทางมีหรือต้องการวิธีการเช่น $wpdb->insert()
หรือ $wpdb->get_var()
แต่ที่เราทำ เพราะพวกเขาประหยัดเวลา ลดจุดบกพร่อง และขจัดคำถามที่ไม่ดีออกไป แล้วฟังก์ชั่นไหนที่ขาดหายไป? ขึ้นอยู่กับโครงการที่คุณกำลังทำงานอยู่ เราต้องการการสนับสนุนสำหรับคำถามสองข้อนี้:
INSERT IGNORE INTO tbl_name ...
INSERT INTO tbl_name ... ON DUPLICATE KEY UPDATE ...
ขั้นตอนที่ #1 – สร้างดรอปอิน
ขั้นตอนการสร้าง DB drop-in นั้นเรียบง่าย และผลลัพธ์สุดท้ายก็จะถูกรวมเข้ากับ WP อย่างราบรื่น
สร้างไฟล์ชื่อ db.php
และวางไว้ในโฟลเดอร์ /wp-content/
ให้ไฟล์เป็นส่วนหัวของปลั๊กอินมาตรฐานและสร้างคลาสที่ขยาย wpdb บางอย่างเช่นนี้:
<?php /* Plugin Name: Extended wpdb Description: A few extra functions for wpdb Version: 1.0 Author: WebFactory Ltd */ class wpdb_extended extends wpdb { public function __construct(){ parent::__construct( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST ); } public function test() { echo 'Extended wpdb is running.'; } } global $wpdb; $wpdb = new wpdb_extended();
ส่วนหัวค่อนข้างอธิบายตนเองได้ วิธีการสร้างทำให้แน่ใจว่าเราสร้างการเชื่อมต่อฐานข้อมูลใหม่เมื่อวัตถุถูกสร้างขึ้นและใช้ตัวสร้าง wpdb ดั้งเดิมสำหรับสิ่งนั้น ค่าคงที่ DB เหล่านั้นถูกกำหนดใน wp-config.php
ดังที่เราได้กล่าวไปแล้วในตอนต้น เราเพียงแค่เพิ่มฟังก์ชันบางอย่างและนำอย่างอื่นมาใช้ใหม่ วิธีการ test()
เป็นเพียงเพื่อดูว่าทุกอย่างถูกต้องหรือไม่
สองบรรทัดสุดท้ายมีความสำคัญ เนื่องจากเป็นคลาสที่กำหนดเอง WP จะไม่สร้างอ็อบเจ็กต์ $wpdb
ให้เราโดยอัตโนมัติ เราต้องทำด้วยตัวเอง อย่าลืมใช้คำสำคัญ global
เพราะไม่เช่นนั้น คุณจะสร้างตัวแปรในเครื่อง
ขั้นตอน #2 – ทดสอบก่อนขุดลึก
เปิดแดชบอร์ด WP ของคุณและตรงไปที่ปลั๊กอิน นอกจากแท็บ ทั้งหมด ใช้งานอยู่ และ ไม่ทำงาน (ปลั๊กอิน) ปกติแล้ว คุณจะเห็นแท็บดร็อปอินและในนั้น คลาสฐานข้อมูลแบบกำหนดเองของเราก็ใช้เวทย์มนตร์บางอย่าง
เนื่องจากผู้ดูแลระบบทำงานอย่างถูกต้อง เรารู้ว่าเราทำงานได้ดี คลาสใหม่ กำหนดเอง แบบขยายของเราพร้อมแล้ว และไม่มีอะไรเปลี่ยนแปลง ยอดเยี่ยม! แต่สำหรับการวัดที่ดี ให้ใส่โค้ดสามบรรทัดนี้ลงใน functions.php
ของธีม (หรือที่ใดที่หนึ่งในปลั๊กอินที่จะเรียกใช้ทันที):
global $wpdb; $wpdb->test(); die;
เรียกใช้ admin หรือ front-end page แล้วคุณเห็นอะไร? “ wpdb แบบขยายกำลังทำงานอยู่ " สมบูรณ์แบบ. ตอนนี้สำหรับการทำงานในโลกแห่งความเป็นจริงของเรา
ขั้นตอน #3 – สร้าง แก้ไข หรือแทนที่ฟังก์ชัน
แบบสอบถาม INSERT IGNORE
ดูเหมือนจะทำได้ง่าย เรามี $wpdb->insert() แล้ว ดังนั้นเราจึงขาดเพียงคำเดียว น่าเสียดาย เนื่องจากไม่มีตัวกรองในที่ที่ถูกต้อง โค้ดนี้จึงไม่ใช่โค้ดสองบรรทัด
หากคุณเปิด wp-db.php และไปที่เมธอด insert()
ในบรรทัด #2100 คุณจะเห็นว่าใช้ _insert_replace_helper()
จากบรรทัด #2151 และฟังก์ชันนั้นไม่มีตัวกรองหรือการดำเนินการเดียว เราไม่สามารถห่อฟังก์ชันได้ เนื่องจากฟังก์ชันจะส่งกลับผลลัพธ์ของคิวรีทันที ไม่ใช่ตัวคิวรีที่เราปรับเปลี่ยนได้ คนเกียจคร้าน เราจะต้องแทนที่ทั้งเมธอด insert()
และ _insert_replace_helper()
เราจะเพิ่มพารามิเตอร์พิเศษ – $ignore
บูลีนที่มีค่าเริ่มต้น false
public function insert( $table, $data, $format = null, $ignore = false ) { return $this->_insert_replace_helper( $table, $data, $format, 'INSERT', $ignore = false ); }
ในกรณีอื่นๆ ฟังก์ชันที่มีห้าพารามิเตอร์จะเป็นตัวเลือกที่ดีในการเปลี่ยนให้เป็นอาร์เรย์ที่เชื่อมโยง แต่เราต้องการความเข้ากันได้แบบย้อนหลัง ดังนั้นเราจึงไม่ทำอย่างนั้น การเปลี่ยนแปลงในฟังก์ชันอื่นก็เล็กน้อยเช่นกัน:
function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT', $ignore = false ) { $this->insert_id = 0; if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) ) { return false; } $data = $this->process_fields( $table, $data, $format ); if ( false === $data ) { return false; } $formats = $values = array(); foreach ( $data as $value ) { if ( is_null( $value['value'] ) ) { $formats[] = 'NULL'; continue; } $formats[] = $value['format']; $values[] = $value['value']; } $fields = '`' . implode( '`, `', array_keys( $data ) ) . '`'; $formats = implode( ', ', $formats ); // modification for IGNORE keyword if (true == $ignore && 'INSERT' == $type) { $type = 'INSERT IGNORE'; } $sql = "$type INTO `$table` ($fields) VALUES ($formats)"; $this->check_current_query = false; return $this->query( $this->prepare( $sql, $values ) ); }
ทำไมนักพัฒนาไม่ทำเช่นนี้บ่อยขึ้น?
หากคุณต้องการเคียวรีแบบกำหนดเองเพียงไม่กี่ครั้ง คุณสามารถใช้ $wpdb->query()
ได้อย่างง่ายดาย ไม่จำเป็นต้องเปลี่ยนคลาสเริ่มต้น คุณยังสามารถเขียนคลาสแบบกำหนดเองที่ขยายคลาสดีฟอลต์แต่ไม่แทนที่อ็อบเจ็กต์ wpdb ในกรณีนั้น คุณจะต้องใช้ $mycustomclass->method()
แต่นั่นไม่ใช่จุดจบของโลก
นอกจากปัจจัยด้านความเย็นที่เห็นได้ชัดซึ่งขยายคลาส wpdb เริ่มต้นเป็นสิ่งที่ควรทำใน WP และไม่แฮ็ก ดังนั้นอย่าลังเลที่จะเล่นกับมัน จำไว้สองสิ่ง:
- เมื่อคุณส่งโครงการของคุณให้ใครบางคน อย่าลืมรวมไฟล์
db.php
; มันจะไม่อยู่ในโฟลเดอร์ธีมหรือปลั๊กอินใด ๆ - จับตาดูการเปลี่ยนแปลงใน
wp-db.php
เนื่องจากอาจส่งผลต่อคลาสที่คุณกำหนดเอง (แม้ว่าจะไม่น่าเป็นไปได้สูง)