ฉันจะเชื่อถือ switch_to_blog () ได้อย่างไร


18

เมื่อฉันโทรswitch_to_blog()ด้วยรหัสบล็อกฉันไม่รู้ว่าบล็อกนั้นมีอยู่จริงหรือไม่ TRUEฟังก์ชั่นผลตอบแทนเสมอ

กรณีทดสอบ:

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

ซึ่งจะส่งผลให้เกิดข้อผิดพลาดของฐานข้อมูลที่ผู้ใช้เห็น ฉันจะป้องกันได้อย่างไร

กรณีใช้งานจริง

ผมเป็นนักพัฒนานำของกดสื่อสารได้หลายภาษา เมื่อผู้ใช้แปลโพสต์เธอจะได้รับหน้าจอดังนี้:

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้สิ่งต่อไปนี้สามารถเกิดขึ้นได้:

  1. เธอบันทึกโพสต์สำเร็จแล้วและทำการแปลโพสต์ต่อไป
  2. ผู้ใช้รายอื่นซึ่งเป็นผู้ดูแลระบบเครือข่ายจะลบบล็อกภาษาเยอรมันในขณะที่เขียน
  3. เธอพบบันทึกอีกครั้งและได้รับข้อผิดพลาดของฐานข้อมูล

ฉันต้องการหลีกเลี่ยงสถานการณ์นั้น ฉันจะตรวจสอบอย่างรวดเร็วได้อย่างไรถ้ามีบล็อกเป้าหมายอยู่ ฉันโทรหาswitch_to_blog()บ่อยในหลาย ๆ คลาสดังนั้นมันจึงต้องเร็ว


วิธีการเกี่ยวกับ$wpdb->blogid;และเบ็ดwp_insert_post_data?
JMau

@JMau get_post()เป็นเพียงการอ่าน อาจมีการหยุดชั่วคราวระหว่างการบันทึกล่าสุดและการโหลดหน้าจอแก้ไขครั้งถัดไป
fuxia

5
เคียวรี SQL ที่แคชต่อคำขอสำหรับ blog_id ในตาราง wp_blogs (ที่ถูกลบ = 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 คิดออกเสียงดังว่ามี ... มีwp_cache_switch_to_blog()แต่จะช่วยให้มีแคชถาวรไม่ได้เป็นค่าเริ่มต้นในสิ่ง WP หน้า อย่างไรก็ตามสำหรับฉันแล้วมันยังไม่ชัดเจนว่าคุณต้องการตรวจสอบการมีอยู่ของบล็อกอย่างไร: เมื่อมีคนลบบล็อกหรือเมื่อมีคนพยายามเขียนโพสต์ที่แปลแล้วซึ่งชี้ไปยังบล็อกอื่น (ใช้เนื้อหาเดียวกันในภาษาอื่น)
ไกเซอร์

คำตอบ:


10

ความคิดของ @ GM ที่จะแคชการตรวจสอบทำให้ฉันไปที่ฟังก์ชันตัวช่วย ฉันได้ใส่ไว้ในเนมสเปซส่วนกลางเพื่อให้สามารถใช้ได้ทุกที่

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

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

การใช้

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

ทำไม$wpdb->get_results+ wp_list_pluckแทนที่จะเป็นเพียง(int) $wpdb->get_var? อย่างไรก็ตาม +1 และฉันคิดว่าสิ่งที่คล้ายกันควรอยู่ใน core switch_to_blog ...
gmazzap

@GM get_var()ส่งคืนผลลัพธ์เดียว ฉันได้ใช้get_col()ตอนนี้และทำให้แน่ใจว่าผลลัพธ์ที่ว่างเปล่าจะไม่ถูกดึงออกมาอีก
fuxia

อ่า ... ฉันอ่านแบบสอบถามได้ดีขึ้นตอนนี้คุณจะได้รับรหัสบล็อกทั้งหมดสำหรับรหัสไซต์เฉพาะตอนแรกอ่านฉันว่าคุณจะได้รับ ID บล็อกเพียงครั้งเดียว (ครั้งที่ผ่านไปฟังก์ชั่น) ... แน่ใจว่าอาร์เรย์ วิธีที่ดีกว่า ฉันขอโทษที่เป็นไปไม่ได้ +1 อีกครั้ง :)
gmazzap
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.