Làm cách nào tôi có thể tin tưởng switch_to_blog ()?


18

Khi tôi gọi switch_to_blog()bằng id blog, tôi không biết liệu blog đó có thực sự tồn tại hay không. Hàm trả về luôn TRUE.

Trường hợp thử nghiệm:

switch_to_blog( PHP_INT_MAX );
$post = get_post( 1 );
restore_current_blog();

Điều này sẽ dẫn đến lỗi cơ sở dữ liệu được tiếp xúc với người dùng. Làm thế nào tôi có thể ngăn chặn điều đó?

Trường hợp sử dụng trong thế giới thực

Tôi là nhà phát triển chính của Báo chí đa ngôn ngữ . Khi người dùng dịch một bài đăng, cô ấy sẽ nhận được một màn hình như thế này:

nhập mô tả hình ảnh ở đây

Bây giờ điều sau đây có thể xảy ra:

  1. Cô lưu bài thành công và tiếp tục dịch bài.
  2. Một người dùng khác, một quản trị viên mạng, xóa blog tiếng Đức trong khi cô ấy đang viết.
  3. Cô nhấn lưu lại và bị lỗi cơ sở dữ liệu.

Tôi muốn tránh kịch bản đó. Làm cách nào để kiểm tra nhanh nếu blog mục tiêu tồn tại? Tôi gọi switch_to_blog()rất thường xuyên trong nhiều lớp khác nhau, vì vậy nó phải nhanh.


Làm thế nào về $wpdb->blogid;và móc wp_insert_post_data?
JMau

@JMau get_post()chỉ là đọc. Có thể có một khoảng dừng dài giữa lần lưu cuối cùng và màn hình chỉnh sửa tiếp theo tải lại.
fuxia

5
Một truy vấn SQL được lưu trong bộ nhớ cache cho mỗi yêu cầu cho blog_id trong bảng wp_bloss (nơi đã xóa = 0)?
gmazzap

1
@GMSELECT blog_id FROM {$wpdb->blogs} WHERE site_id = %d AND public = '1' AND archived = '0' AND spam = '0' AND deleted = '0'
kaiser

@toscho Suy nghĩ thành tiếng ... Có wp_cache_switch_to_blog(), nhưng nó chỉ giúp với bộ nhớ cache liên tục, không phải mặc định trên trang WP. Dù sao, với tôi nó không thực sự rõ ràng nơi bạn muốn kiểm tra sự tồn tại của blog: Khi ai đó xóa blog hoặc khi ai đó cố gắng viết bài dịch được trỏ đến một blog khác (cung cấp cùng một nội dung bằng ngôn ngữ khác)?
kaiser

Câu trả lời:


10

Ý tưởng của @ GM để lưu trữ kiểm tra đã đưa tôi đến chức năng trợ giúp sau. Tôi đã đặt nó vào không gian tên toàn cầu để có sẵn ở mọi nơi.

Hàm không nói gì về trạng thái blog, chỉ khi nó tồn tại và không được đánh dấu là đã xóa. Truy vấn cơ sở dữ liệu rất nhanh (0,0001 giây) và chỉ chạy một truy vấn trên mỗi id trang web, bất kể chức năng được gọi thường xuyên như thế nào.

if ( ! function_exists( 'blog_exists' ) ) {

    /**
     * Checks if a blog exists and is not marked as deleted.
     *
     * @link   http://wordpress.stackexchange.com/q/138300/73
     * @param  int $blog_id
     * @param  int $site_id
     * @return bool
     */
    function blog_exists( $blog_id, $site_id = 0 ) {

        global $wpdb;
        static $cache = array ();

        $site_id = (int) $site_id;

        if ( 0 === $site_id )
            $site_id = get_current_site()->id;

        if ( empty ( $cache ) or empty ( $cache[ $site_id ] ) ) {

            if ( wp_is_large_network() ) // we do not test large sites.
                return TRUE;

            $query = "SELECT `blog_id` FROM $wpdb->blogs
                    WHERE site_id = $site_id AND deleted = 0";

            $result = $wpdb->get_col( $query );

            // Make sure the array is always filled with something.
            if ( empty ( $result ) )
                $cache[ $site_id ] = array ( 'do not check again' );
            else
                $cache[ $site_id ] = $result;
        }

        return in_array( $blog_id, $cache[ $site_id ] );
    }
}

Sử dụng

if ( ! blog_exists( $blog_id ) )
    return new WP_Error( '410', "The blog with the id $blog_id has vanished." );

Tại sao $wpdb->get_results+ wp_list_pluckthay vì chỉ (int) $wpdb->get_var? tuy nhiên +1 và tôi nghĩ rằng một cái gì đó tương tự nên có trong core switch_to_blog ...
gmazzap

@GM get_var()trả về chỉ một kết quả. get_col()Bây giờ tôi đã sử dụng và tôi chắc chắn rằng một kết quả trống sẽ không được tải lại.
fuxia

À ok ... Tôi tốt hơn nên đọc truy vấn ngay bây giờ, bạn nhận được tất cả các id blog cho một id trang web cụ thể, lúc đầu tôi đọc, bạn chỉ nhận được một id blog tại một thời điểm (một cái được truyền vào chức năng) ... chắc chắn là mảng cách tốt hơn Tôi xin lỗi không thể +1 lần nữa :)
gmazzap
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.