restore_cản_blog () so với switch_to_blog ()


23

Sau mỗi phiên bản switch_to_blog()bạn nên gọi restore_current_blog()để khôi phục blog hiện tại (thực tế, trước đó).

Nhưng nếu bạn đang lặp qua hai hoặc nhiều blog và gọi switch_to_blog()từng blog , có lý do gì để không sử dụng bổ sung switch_to_blog()ở cuối vòng lặp để chuyển sang blog ban đầu thay vì gọi restore_current_blog()ở mỗi lượt.

Ví dụ

Tại sao không:

 $original_blog_id = get_current_blog_id();
 foreach( $blog_ids as $blog_id ){
    switch_to_blog( $blog_id );
    //Do stuff
 }
 switch_to_blog( $original_blog_id );

thay vì:

 foreach( $blog_ids as $blog_id ){
    switch_to_blog( $blog_id );
    //Do stuff
    restore_current_blog_id();
 }

Bây giờ tôi hiểu điều này, cảm ơn vì đã sửa câu trả lời của tôi;) Đang sửa đổi mọi thứ.
brasofilo

Câu trả lời:


19

Sau mỗi trường hợp switch_to_blog()bạn cần gọi restore_current_blog()nếu không WP sẽ nghĩ rằng nó đang ở chế độ "đã chuyển" và có khả năng trả về dữ liệu không chính xác.

Nếu bạn xem mã nguồn cho cả hai chức năng, bạn sẽ thấy các chức năng đó đẩy / bật dữ liệu vào toàn cầu $GLOBALS['_wp_switched_stack'] . Nếu bạn không gọi restore_current_blog()sau mỗi lần switch_to_blog(), $GLOBALS['_wp_switched_stack']sẽ không trống. Nếu $GLOBALS['_wp_switched_stack']WP không trống thì nghĩ rằng nó đang ở chế độ chuyển đổi, ngay cả khi bạn đã quay lại blog ban đầu bằng cách sử dụng switch_to_blog(). Các chức năng chế độ chuyển đổi là ms_is_switched()và nó ảnh hưởng wp_upload_dir(). Nếu wp_upload_dir()nghĩ rằng nó ở chế độ chuyển đổi, nó có thể trả về dữ liệu không chính xác. wp_upload_dir()xây dựng URL cho trang web, vì vậy đây là một chức năng rất quan trọng.

Đây là cách sử dụng đúng:

 foreach( $blog_ids as $blog_id ){
    switch_to_blog( $blog_id );
    //Do stuff
    restore_current_blog();
 }

Cảm ơn, tôi đã không có cơ hội làm việc thông qua các hằng số & logic wp_upload_dir()sử dụng để tạo ra các url, nhưng tôi sẽ nói với bạn rằng điều này thực sự dẫn đến hành vi lỗi. Trong mọi trường hợp, sự tồn tại của ms_is_switched()phương tiện thay thế của tôi dẫn đến chức năng không hoạt động như mong đợi và có thể phá vỡ các trình cắm cũng như cốt lõi. Cảm ơn
Stephen Harris

1
Nếu điều này là đúng, thì trang Codex restore_current_blog()cần cập nhật, vì nó nói rằng đối với nhiều thiết bị chuyển mạch, người ta chỉ cần lưu hiện tại $blog_idvà sau đó sử dụng nhiều switch_to_blog()cuộc gọi.
Pat J

16

Nếu bạn muốn chạy trên nhiều blog, không cần phải khôi phục blog trước đó mỗi lần. Điều duy nhất phát triển là $GLOBALS['_wp_switched_stack']- một mảng với ID blog, không có gì phải lo lắng.

Nhưng hãy nhớ, restore_current_blog() sẽ không hoạt động (!!) Sau lần chuyển đổi thứ hai, bởi vì nó sử dụng blog trước đó - không phải là blog đầu tiên sau đó. Vì vậy, hãy lưu trữ ID blog đầu tiên và gọi điện

switch_to_blog( $first_blog_id ); 
unset ( $GLOBALS['_wp_switched_stack'] );
$GLOBALS['switched'] = false; 

… thay vì restore_current_blog() khi bạn hoàn thành. Các biến toàn cục phải được đặt lại hoặc bạn sẽ gặp phải các vấn đề được đề cập bởi @ user42826.

Tác động hiệu suất là rất lớn. Tôi đã chạy một số thử nghiệm trên bản cài đặt cục bộ với 12 trang web:

$sites = wp_get_sites();

print '<pre>' . count( $sites ) . " sites\n";

timer_start();

print 'With restore_current_blog():    ';

foreach ( $sites as $site ) {
    switch_to_blog( $site[ 'blog_id' ] );
    restore_current_blog();
}

timer_stop( 1, 9 );

print "\nWithout restore_current_blog(): ";

timer_start();

$current_site = get_current_blog_id();

foreach ( $sites as $site ) {
    switch_to_blog( $site[ 'blog_id' ] );
}

switch_to_blog( $current_site );
$GLOBALS['_wp_switched_stack'] = array();
$GLOBALS['switched']           = FALSE;

timer_stop( 1, 9 );

print '</pre>';

Kết quả:

12 sites
With restore_current_blog():    0.010648012
Without restore_current_blog(): 0.005203962

Sử dụng restore_current_blog()sau mỗi chuyển đổi nhân đôi thời gian cần thiết chỉ để chuyển đổi.


Nghĩ rằng không có lý do gì để không. Đã nhầm lẫn tại sao restore_current_blog()không truy xuất ID blog trước đó và gọi switch_to_blog()- một cái nhìn ngắn gọn về nguồn mã và có vẻ như có một chút sao chép mã ...
Stephen Harris

3
Tôi không nghĩ rằng sửa đổi trực tiếp các quả cầu là một ý tưởng hay, bởi vì bạn đang ghép mã của mình với các phần bên trong của Core, điều này không phải là bằng chứng trong tương lai. Tốt hơn là sử dụng API đúng cách.
Ian Dunn

2
@IanDunn Chỉ dành cho bản ghi: switch_to_blog()là một API rất hạn chế (bị hỏng). Nếu WordPress khắc phục điều đó , chúng ta phải cấu trúc lại mã của mình. Và WordPress sẽ không bao giờ từ bỏ toàn cầu yêu thích của mình.
fuxia

2
@IanDunn I don't think modifying the globals directly is a good idea, đừng nói điều đó với các nhà phát triển cốt lõi của wp;)
Ejaz

1
@JD Tất nhiên, bạn cần phải nhận thức được bối cảnh. Trong trường hợp trạng thái đã được chuyển đổi, bạn thậm chí có thể phải duy trì chỉ mục chính xác của ngăn xếp. Tôi có lẽ sẽ tìm kiếm một cách để tránh điều đó. Mặt khác, đây là WordPress, vì vậy có thể không còn cách nào khác nữa
Fuxia

1

Cảm ơn câu trả lời @toscho. Yêu cầu này trong hàng đợi của WP - xem cập nhật tại đây . Cho đến khi được sửa trong WP, nếu bất kỳ ai muốn sử dụng tiêu chuẩn restore_current_blog(), thì đây là một phương pháp khác (vui lòng sửa nếu tôi sai):

làm cho chức năng của bạn, tức là

function restore_original_blog_X(){

    if(!empty(($GLOBALS['_wp_switched_stack'][0])){
        $GLOBALS['blog_id']= $GLOBALS['_wp_switched_stack'][0];
        $GLOBALS['_wp_switched_stack'] = array($GLOBALS['_wp_switched_stack'][0]);
        restore_current_blog();
    }

}

và chỉ thực hiện một lần khi bạn hoàn thành nhiều công tắc. (thêm: wp-gồm / ms-blog.php )

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.