nhận tất cả các giá trị cho khóa trường tùy chỉnh (bài chéo)


44

Tôi biết làm thế nào để có được một giá trị trường tùy chỉnh cho một bài viết cụ thể.

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

Những gì tôi cần là để có được tất cả các giá trị được liên kết với một khóa bài tùy chỉnh cụ thể, trên tất cả các bài viết .

Bất cứ ai cũng biết một cách hiệu quả để làm điều này? Tôi sẽ không muốn lặp qua tất cả các id bài trong DB.

Thí dụ:

4 bài đăng tất cả với các giá trị khác nhau cho một trường tùy chỉnh được gọi là 'Tâm trạng'. 2 bài đăng có giá trị 'hạnh phúc', 1 bài đăng có 'tức giận' và 1 bài đăng có 'buồn'

Tôi muốn xuất ra: trên tất cả các bài viết chúng tôi có: hai tác giả vui, một tức giận và một tác giả buồn.

Nhưng đối với rất nhiều bài viết.

Những gì tôi đang tìm kiếm là:

  • một chức năng WP để có được điều này. hoặc là
  • một truy vấn tùy chỉnh để có được điều này hiệu quả nhất có thể.

5
Có vẻ như bạn đang sử dụng điều này như một nguyên tắc phân loại. Tại sao không chỉ đơn giản (tự động) thêm một thuật ngữ cho các bài đăng này khi lưu? Sẽ làm cho truy vấn dễ dàng hơn nhiều.
kaiser

@kaiser Tôi không thể cảm ơn bạn đủ vì đã trở thành một thiên tài!
user2128576

Câu trả lời:


58

Một cách tiếp cận có thể là sử dụng một trong các phương thức của trình trợ giúp trong lớp WPDB để thực hiện một truy vấn dựa trên meta được tinh chỉnh hơn. Tuy nhiên, lưu ý khi sử dụng một số chức năng này là bạn thường không lấy lại được một mảng dữ liệu đơn giản và thường phải thực hiện các tham chiếu không cần thiết đến các thuộc tính đối tượng, ngay cả khi bạn chỉ gọi một cột hoặc hàng.

Tất nhiên, không phải tất cả các hàm đều giống nhau và một đề cập có chủ đích đi ra phương thức WPDB , get_colnó trả về một mảng phẳng đơn giản của dữ liệu được truy vấn, tôi thực hiện đề cập này một cách cụ thể bởi vì ví dụ sau sẽ gọi phương thức này .

WordPress - WPDB Chọn một cột dữ liệu
$ wpdb-> get_col ()

Đây là một chức năng ví dụ truy vấn cơ sở dữ liệu cho tất cả các bài đăng của loại bài đăng đã chọn, trạng thái bài đăng và với một khóa meta cụ thể (hoặc trường tùy chỉnh theo ý ít kỹ thuật hơn).

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;
}

Vì vậy, ví dụ, nếu bạn muốn tìm ra bài đăng nào có khóa meta xếp hạng , đối với phim loại bài đăng và bạn muốn lưu trữ thông tin đó bên trong một biến, một ví dụ về cuộc gọi như vậy sẽ là ..

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

Nếu bạn không muốn làm gì hơn là in dữ liệu đó ra màn hình, hàm implode của PHP có thể nhanh chóng ghép mảng đơn giản đó thành các dòng dữ liệu.

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

Bạn cũng có thể sử dụng dữ liệu được trả về để tìm ra có bao nhiêu bài đăng có các giá trị meta này bằng cách thực hiện một vòng lặp đơn giản trên dữ liệu được trả về và xây dựng một mảng các số đếm, ví dụ.

$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.
*/

Logic này có thể được áp dụng cho các loại dữ liệu khác nhau và được mở rộng để hoạt động với bất kỳ số lượng các cách khác nhau. Vì vậy, tôi hy vọng các ví dụ của tôi đã hữu ích và đủ đơn giản để làm theo.


3
Ngoài ra, thực tế thú vị cho người xem trong tương lai, nếu bạn chỉ muốn kéo các giá trị meta duy nhất - bạn nhập DISTINCTngay sau SELECTchức năng trên. Có thể hữu ích.
Howdy_McGee

Tôi nghĩ rằng điều này cực kỳ hữu ích
Pablo SG Pacheco

Làm thế nào để làm điều này và trả về các giá trị đã được sắp xếp?, Tôi nghĩ rằng bằng cách sử dụng ĐẶT HÀNG nhưng tôi không thể tìm ra cách sử dụng nó
efirvida

14

Tôi chỉ muốn thêm một điều nhỏ vào mã của t31os ở trên. Tôi đã thay đổi "CHỌN" thành "CHỌN DISTINCT" để loại bỏ các mục trùng lặp khi tôi sử dụng mã này.


1
Tôi có thể tưởng tượng các trường hợp sẽ có nhiều giá trị meta có cùng giá trị và do đó không tạo ra sự bổ sung đó vào mã của tôi. Nếu bạn muốn các giá trị riêng biệt, đây sẽ là cách để đi. Ngoài ra, bạn cũng có thể thêm nó dưới dạng đối số cho hàm (để bạn có thể sử dụng nó hoặc không, nếu phù hợp).
t31os

10

Việc sử dụng $ wpdb toàn cầu là không tốt hoặc cần thiết:

// 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 );

Đây sẽ là phương pháp ưa thích của tôi để làm điều đó, trong hầu hết các trường hợp. Nó thực hiện năm truy vấn, thay vì chỉ một, nhưng, vì nó sử dụng các quy trình WordPress tiêu chuẩn để tạo và gửi chúng, bất kỳ bộ nhớ đệm dành riêng cho nền tảng nào (như Bộ nhớ đệm đối tượng của WP Engine hoặc một số plugin ngẫu nhiên) sẽ khởi động. được lưu trữ trong bộ nhớ cache nội bộ của WordPress trong suốt thời gian yêu cầu, do đó sẽ không cần phải truy xuất lại từ cơ sở dữ liệu nếu cần.
Andrew Dinmore

Bất kỳ bộ lọc nào cũng sẽ được áp dụng cho dữ liệu, có thể cực kỳ quan trọng, ví dụ, một trang web đa ngôn ngữ. Cuối cùng, vì nó chỉ sử dụng các chức năng cốt lõi của WordPress tiêu chuẩn, nên nó ít có khả năng bị phá vỡ bởi một bản cập nhật trong tương lai.
Andrew Dinmore

4

cách nhanh nhất sẽ là truy vấn sql tùy chỉnh và tôi không chắc nhưng bạn có thể thử

$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
");

Nếu bất cứ điều gì thì đó là một sự khởi đầu.


1
cảm ơn, nhưng không nên tránh các câu hỏi tùy chỉnh 'bằng mọi giá'? Tôi thích sử dụng lớp trừu tượng WP (đó có phải là cái gọi là gì không?) ... nhưng tất nhiên nếu điều này là không thể ..
mikkelbreum

Các truy vấn tùy chỉnh, nếu được viết đúng cách, có thể tốt hơn và bạn chỉ nên tránh chúng nếu bạn không biết bạn đang làm gì.
Bai Internet

1
Tôi đồng ý với các truy vấn mwb .custom rất hữu ích và thiết thực, nhưng tôi nghĩ rằng chúng cũng nặng hơn nhiều trên DB .. đặc biệt là sử dụng các hàm SRT ..
krembo99

3

Để nhận tất cả các giá trị meta bằng một khóa meta

Kiểm tra wp-> db wordpress codex

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

3
Vấn đề với cách tiếp cận này là thiếu tính cụ thể, bạn sẽ nhận được nhiều kết quả từ một truy vấn như vậy, có thể bao gồm các bản nháp, mục rác, bài đăng, trang và bất kỳ loại bài đăng nào khác tồn tại. Bạn không bao giờ nên truy vấn những gì bạn không cần, tính cụ thể chắc chắn là bắt buộc ở đây.
t31os

Mặc dù đúng là bạn có thể nhận được các giá trị từ các loại bài đăng và trạng thái khác, có những lúc tất cả những gì bạn cần là các giá trị và bạn đã không sử dụng meta_key đó ở bất cứ đâu ngoài nơi bạn cần. Nếu tất cả / hầu hết các giá trị là duy nhất, đây có thể là giải pháp tốt nhất.
Luke Gedeon

2

Không có lý do tại sao bạn không thể hợp nhất mã của t31os và BaiNET để có một câu lệnh được chuẩn bị có thể sử dụng lại (kiểu wordpress) trả về số lượng và các giá trị trong một hoạt động hiệu quả.

Đó là một truy vấn tùy chỉnh nhưng nó vẫn sử dụng lớp trừu tượng cơ sở dữ liệu wordpress - vì vậy, chẳng hạn như tên bảng thực sự là gì, hoặc nếu chúng thay đổi, và đó là một tuyên bố được chuẩn bị để chúng ta an toàn hơn nhiều từ các cuộc tấn công SQL, v.v. .

Trong trường hợp này, tôi không còn kiểm tra loại bài đăng và tôi đang loại trừ các chuỗi trống:

    $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;

Trong đó đặc biệt là

Điều này sẽ trả về một mảng các đối tượng như vậy:

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

Sử dụng như sau với foreach

 $key = get_post_custom_values( 'key' );

Giả sử tên khóa của trường tùy chỉnh của bạn là


Lưu ý rằng điều này mặc định cho bài viết hiện tại, khi không có post_id được chỉ định.
bạch dương
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.