รับค่าทั้งหมดสำหรับคีย์ฟิลด์ที่กำหนดเอง (cross-post)


44

ฉันรู้วิธีรับค่าฟิลด์ที่กำหนดเองสำหรับโพสต์ที่เฉพาะเจาะจง

get_post_meta($post_id, $key, $single);

สิ่งที่ฉันต้องการคือการได้รับค่าทั้งหมดที่เกี่ยวข้องกับการโพสต์สำคัญโดยเฉพาะที่กำหนดเองข้ามโพสต์ทั้งหมด

ใครรู้วิธีที่มีประสิทธิภาพในการทำเช่นนี้? ฉันไม่ต้องการวนซ้ำทุกโพสต์ id ในฐานข้อมูล

ตัวอย่าง:

4 โพสต์ทั้งหมดที่มีค่าแตกต่างกันสำหรับฟิลด์ที่กำหนดเองที่เรียกว่า 'อารมณ์' 2 โพสต์มีค่า 'ความสุข', 1 โพสต์มี 'โกรธ' และ 1 โพสต์มี 'เศร้า'

ฉันต้องการที่จะแสดงผล: ในโพสต์ทั้งหมดที่เรามี: มีความสุขสองคนโกรธคนหนึ่งและผู้เขียนเศร้าคนหนึ่ง

แต่สำหรับโพสต์จำนวนมาก

สิ่งที่ฉันกำลังมองหาคือ:

  • ฟังก์ชั่น WP เพื่อรับสิ่งนี้ หรือ
  • แบบสอบถามที่กำหนดเองเพื่อให้ได้สิ่งนี้อย่างมีประสิทธิภาพที่สุด

5
ดูเหมือนว่าคุณกำลังใช้สิ่งนี้เป็นอนุกรมวิธาน ทำไมไม่เพิ่มคำศัพท์ (อัตโนมัติ) ลงในโพสต์เหล่านี้เมื่อทำการบันทึก จะทำให้การสืบค้นง่ายขึ้นมาก
ไกเซอร์

@kaiser ฉันไม่สามารถขอบคุณมากพอสำหรับการเป็นอัจฉริยะ!
user2128576

คำตอบ:


58

วิธีหนึ่งที่เป็นไปได้คือใช้วิธีการช่วยเหลืออย่างใดอย่างหนึ่งในคลาส WPDB เพื่อทำแบบสอบถามที่ใช้เมตาที่ละเอียดกว่า ข้อแม้ที่จะใช้ฟังก์ชั่นเหล่านี้คือคุณไม่ได้รับข้อมูลกลับมาง่ายๆและมักจะต้องทำการอ้างอิงโดยไม่จำเป็นกับคุณสมบัติของวัตถุแม้ว่าคุณจะเรียกใช้เพียงหนึ่งคอลัมน์หรือหนึ่งแถว

แน่นอนว่าไม่ใช่ทุกฟังก์ชั่นที่มีฟังก์ชั่นเหมือนกันและการเอ่ยถึงอย่างเด็ดเดี่ยวไปยังวิธีการของWPDBget_colซึ่งจะคืนค่าอาเรย์แบนราบที่เรียบง่ายของข้อมูลที่ถูกสอบถามฉันพูดถึงเรื่องนี้โดยเฉพาะ .

WordPress - WPDB การเลือกคอลัมน์ของข้อมูล
$ wpdb-> get_col ()

นี่คือตัวอย่างฟังก์ชันที่สืบค้นฐานข้อมูลสำหรับโพสต์ทั้งหมดของประเภทโพสต์ที่เลือกสถานะการโพสต์และคีย์เมตาเฉพาะ (หรือฟิลด์ที่กำหนดเองไปยังจิตใจที่มีเทคนิคน้อย)

function get_meta_values( $key = '', $type = 'post', $status = 'publish' ) {

    global $wpdb;

    if( empty( $key ) )
        return;

    $r = $wpdb->get_col( $wpdb->prepare( "
        SELECT pm.meta_value FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = %s 
        AND p.post_status = %s 
        AND p.post_type = %s
    ", $key, $status, $type ) );

    return $r;
}

ดังนั้นสำหรับตัวอย่างเช่นถ้าคุณต้องการที่จะหาที่โพสต์มีคีย์เมตาของคะแนนสำหรับประเภทโพสต์ภาพยนตร์และคุณต้องการที่จะเก็บข้อมูลที่อยู่ภายในตัวแปรตัวอย่างของการเรียกร้องดังกล่าวจะเป็น ..

$movie_ratings = get_meta_values( 'rating', 'movies' );

หากคุณไม่ต้องการทำอะไรมากไปกว่าการพิมพ์ข้อมูลนั้นไปยังหน้าจอฟังก์ชั่น implode ของ PHP สามารถแยกอาร์เรย์ที่เรียบง่ายออกเป็นบรรทัดของข้อมูลได้อย่างรวดเร็ว

// Print the meta values seperate by a line break
echo implode( '<br />', get_meta_values( 'YOURKEY' ));

คุณยังสามารถใช้ข้อมูลที่ส่งคืนเพื่อคำนวณจำนวนโพสต์ที่มีค่าเมตาเหล่านี้โดยทำการวนซ้ำแบบง่าย ๆ กับข้อมูลที่ส่งคืนและสร้างอาร์เรย์ของจำนวนตัวอย่างเช่น

$movie_ratings = get_meta_values( 'rating', 'movies' );
if( !empty( $movie_ratings ) ) {
    $num_of_ratings = array();
    foreach( $movie_ratings as $meta_value )
        $num_of_ratings[$meta_value] = ( isset( $num_of_ratings[$meta_value] ) ) ? $num_of_ratings[$meta_value] + 1 : 1;
}

/*
Result:
Array(
    [5] => 10
    [9] => 2
)
// ie. there are 10 movie posts with a rating of 5 and 2 movie posts with a rating of 9.
*/

ตรรกะนี้สามารถนำไปใช้กับข้อมูลประเภทต่างๆและขยายการทำงานได้หลายวิธี ดังนั้นฉันหวังว่าตัวอย่างของฉันจะมีประโยชน์และเรียบง่ายพอที่จะติดตาม


3
นอกจากนี้ยังเป็นเรื่องสนุกสำหรับผู้ชมในอนาคตหากคุณต้องการดึงเฉพาะค่าเมตาที่ไม่ซ้ำกัน - คุณพิมพ์DISTINCTหลังจากSELECTฟังก์ชั่นด้านบน อาจมีประโยชน์
Howdy_McGee

ฉันคิดว่านี่เป็นประโยชน์อย่างมาก
Pablo SG Pacheco

ฉันจะทำสิ่งนี้ได้อย่างไรและคืนค่าที่เรียงลำดับแล้วฉันคิดว่าการใช้ ORDER โดย แต่ฉันไม่สามารถหาวิธีใช้ได้
efirvida

14

ฉันต้องการเพิ่มสิ่งเล็ก ๆ ลงในรหัส t31osด้านบน ฉันเปลี่ยน "SELECT" เป็น "SELECT DISTINCT" เพื่อกำจัดรายการที่ซ้ำกันเมื่อฉันใช้รหัสนี้ด้วยตนเอง


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

10

ไม่ดีหรือจำเป็นต้องใช้ $ wpdb ทั่วโลก:

// function to grab all possible meta values of the chosen meta key.
function get_meta_values( $meta_key,  $post_type = 'post' ) {

    $posts = get_posts(
        array(
            'post_type' => $post_type,
            'meta_key' => $meta_key,
            'posts_per_page' => -1,
        )
    );

    $meta_values = array();
    foreach( $posts as $post ) {
        $meta_values[] = get_post_meta( $post->ID, $meta_key, true );
    }

    return $meta_values;

}

$meta_values = get_meta_values( $meta_key, $post_type );

นี่จะเป็นวิธีที่ฉันชอบในกรณีส่วนใหญ่ มันสร้างข้อความค้นหาห้ารายการแทนที่จะเป็นเพียงข้อความเดียว แต่เนื่องจากมันใช้วิธีมาตรฐานของ WordPress ในการสร้างและส่งมันการแคชเฉพาะแพลตฟอร์มใด ๆ (เช่นการแคชวัตถุของ WP Engine หรือปลั๊กอินแบบสุ่ม) จะเริ่มขึ้น ถูกเก็บไว้ในแคชภายในของ WordPress ตลอดระยะเวลาของการร้องขอดังนั้นจึงไม่จำเป็นต้องดึงข้อมูลจากฐานข้อมูลอีกครั้งหากจำเป็น
Andrew Dinmore

ตัวกรองใด ๆ จะถูกนำไปใช้กับข้อมูลซึ่งอาจมีความสำคัญอย่างยิ่งในตัวอย่างเช่นไซต์ที่มีหลายภาษา ท้ายสุดเนื่องจากมันใช้เพียงฟังก์ชั่นหลักของ WordPress มาตรฐานจึงมีโอกาสน้อยที่จะถูกทำลายโดยการอัพเดทในอนาคต
Andrew Dinmore

4

วิธีที่เร็วที่สุดจะเป็นข้อความค้นหา sql ที่กำหนดเองและฉันไม่แน่ใจ แต่คุณสามารถลองได้

$wpdb->get_results("
  SELECT posts.* , COUNT(*) 'moodcount'
  FROM $wpdb->posts as posts
  JOIN $wpdb->postmeta as postmeta
  ON postmeta.post_id = posts.ID
  AND postmeta.meta_key = 'Mood'
  GROUP BY postmeta.meta_key
");

หากมีอะไรแล้วมันเริ่มต้น


1
ขอบคุณ แต่ไม่ควรหลีกเลี่ยงการทำแบบสอบถามที่กำหนดเองโดยไม่คิดค่าใช้จ่ายเลย ฉันชอบที่จะใช้ชั้น WP นามธรรม (คือว่าสิ่งที่มันเรียกว่า?) ... แต่แน่นอนถ้าเป็นไปไม่ได้ ..
mikkelbreum

ข้อความค้นหาที่กำหนดเองหากเขียนถูกวิธีจะดีกว่าและคุณควรหลีกเลี่ยงหากคุณไม่รู้ว่าคุณกำลังทำอะไรอยู่
Bainternet

1
ฉันเห็นด้วยกับคำถาม mwb .custom มีประโยชน์มากและใช้งานได้จริง แต่ฉันคิดว่ามันหนักกว่า DB มากโดยเฉพาะการใช้ฟังก์ชั่น SRT ..
krembo99

3

สำหรับการรับค่าเมตาทั้งหมดโดยใช้เมตาคีย์

ตรวจสอบ wp-> db wordpress codex

$values = $wpdb->get_col("SELECT meta_value
    FROM $wpdb->postmeta WHERE meta_key = 'yourmetakey'" );

3
ปัญหาของวิธีนี้คือการขาดความเฉพาะเจาะจงคุณจะได้รับผลลัพธ์มากมายจากแบบสอบถามดังกล่าวซึ่งอาจรวมถึงฉบับร่างรายการที่อยู่ในถังขยะโพสต์หน้าและประเภทโพสต์อื่น ๆ ที่มีอยู่ คุณไม่ควรสอบถามสิ่งที่คุณไม่ต้องการความเฉพาะเจาะจงเป็นสิ่งจำเป็นอย่างยิ่งที่นี่
t31os

แม้ว่าจะเป็นความจริงที่ว่าคุณสามารถรับค่าจากประเภทโพสต์และสถานะอื่น ๆ มีบางครั้งที่คุณต้องการทั้งหมดคือค่าและคุณยังไม่ได้ใช้ meta_key นั้นทุกที่ยกเว้นที่คุณต้องการ หากค่าทั้งหมด / ส่วนใหญ่ไม่เหมือนใครนี่อาจเป็นทางออกที่ดีที่สุด
Luke Gedeon

2

ไม่มีเหตุผลใดที่คุณไม่สามารถรวม t31os และรหัสของ Bainternet เพื่อให้มีการจัดทำคำสั่งที่นำมาใช้ใหม่ (สไตล์ WordPress) ที่ส่งกลับการนับและค่าในการดำเนินงานที่มีประสิทธิภาพเพียงครั้งเดียว

มันเป็นเคียวรีที่กำหนดเอง แต่ยังคงใช้เลเยอร์ abstraction abstraction ฐานข้อมูล - ตัวอย่างเช่นมันไม่สำคัญว่าชื่อตารางคืออะไรหรือถ้ามันเปลี่ยนไปและมันเป็นคำสั่งที่เตรียมไว้ดังนั้นเราจึงปลอดภัยจากการโจมตีของ SQL เป็นต้น .

ในกรณีนี้ฉันไม่ได้ตรวจสอบประเภทโพสต์อีกต่อไปและฉันไม่รวมสตริงว่าง:

    $r = $wpdb->get_results(  $wpdb->prepare( "
        SELECT pm.meta_value AS name, count(*) AS count  FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = '%s'
        AND pm.meta_value != '' 
        AND p.post_type = '%s'
        GROUP BY pm.meta_value
        ORDER BY pm.meta_value          
        ", $key, $type) 
        );
    return $r;

ในครั้งนี้โดยเฉพาะคือ

สิ่งนี้จะส่งคืนอาร์เรย์ของวัตถุดังนี้:

array  
 0 => 
 object(stdClass)[359]
  public 'name' => string 'Hamish' (length=6)
  public 'count' => string '3' (length=1)
 1 => 
 object(stdClass)[360]
  public 'name' => string 'Ida' (length=11)
  public 'count' => string '1' (length=1)
 2 => 
 object(stdClass)[361]
  public 'name' => string 'John' (length=12)
  public 'count' => string '1' (length=1)

0

ใช้สิ่งต่อไปนี้กับ foreach

 $key = get_post_custom_values( 'key' );

ถือว่าชื่อของคีย์ฟิลด์ที่กำหนดเองของคุณคือ


โปรดทราบว่านี่เป็นค่าเริ่มต้นของโพสต์ปัจจุบันเมื่อไม่ได้ระบุ post_id
Birgire
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.