switch_to_blog ()를 어떻게 신뢰할 수 있습니까?


18

switch_to_blog()블로그 ID로 전화 를 걸면 해당 블로그가 실제로 존재하는지 여부를 알 수 없습니다. 이 함수는 항상을 반환합니다 TRUE.

테스트 사례 :

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

이로 인해 데이터베이스 오류가 발생하여 사용자에게 노출됩니다. 어떻게 방지 할 수 있습니까?

실제 사용 사례

저는 Multilingual Press 의 수석 개발자였습니다 . 사용자가 게시물을 번역하면 다음과 같은 화면이 나타납니다.

여기에 이미지 설명을 입력하십시오

이제 다음이 발생할 수 있습니다.

  1. 그녀는 게시물을 성공적으로 저장하고 게시물을 계속 번역합니다.
  2. 네트워크 관리자 인 다른 사용자는 글을 쓰는 동안 독일어 블로그를 삭제합니다.
  3. 저장을 다시 누르면 데이터베이스 오류가 발생합니다.

그 시나리오를 피하고 싶습니다. 대상 블로그가 있는지 빠르게 확인하려면 어떻게 합니까? switch_to_blog()여러 클래스에서 매우 자주 전화 하므로 속도가 빠릅니다.


방법에 대한 $wpdb->blogid;후크 wp_insert_post_data?
JMau

@JMau get_post()는 단지 읽기입니다. 마지막 저장과 다음 편집 화면 재로드 사이에 오래 일시 정지 될 수 있습니다.
fuxia

5
wp_blogs 테이블의 blog_id에 대한 요청 당 캐시 된 SQL 쿼리 (삭제 된 위치 = 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'
황제

@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, 그리고 비슷한 것이 핵심 switch_to_blog에 있어야한다고 생각합니다 ...
gmazzap

@GM get_var()은 하나의 결과 만 반환합니다. 나는 지금 사용 get_col()했고 빈 결과를 다시 가져 오지 않았는지 확인했다.
fuxia

아 괜찮아요 .. 이제 쿼리를 읽는 것이 좋습니다. 특정 사이트 ID에 대한 모든 블로그 ID를 얻습니다. 처음에 읽을 때 한 번에 하나의 블로그 ID (기능에 전달 된 블로그 ID) 만 얻습니다 ... 배열을 확인하십시오 방법이 더 좋습니다. 죄송합니다 다시 +1 할 수 없습니다 :)
gmazzap
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.