Cách chuyển các biến ngoài cho bộ lọc / hành động


11

Tôi thấy mình cần truyền dữ liệu tùy chỉnh vào bộ lọc được cung cấp bởi plugin bên thứ 3. Tất cả những cách tôi đã thấy để làm điều này thực sự phức tạp và khó khăn để quấn đầu tôi.

Lấy ví dụ này:

$score = 42; //Some crazy calculation I don't want to repeat.

function add_score_to_title($title) {
    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');

Làm thế nào tôi có thể truyền $scorebiến cho add_score_to_title()?

Điều cuối cùng tôi làm là thêm biến của mình vào $wpđối tượng toàn cầu . Vì vậy, bạn kết thúc với điều này:

global $wp;
$score = 42; //Some crazy calculation I don't want to repeat.
$wp->some_random_name_for_score = $score;

function add_score_to_title($title) {
    global $wp;
    $score = $wp->some_random_name_for_score;
    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');

Dơ bẩn? Có lẽ. Đơn giản? Vâng Bất kỳ nhược điểm của kỹ thuật này? Vui lòng bàn luận.

CẬP NHẬT Đây là mã hoàn chỉnh trong câu hỏi -> http://pastebin.com/fkSXY04m


Đơn giản chỉ cần thực hiện "tính toán điên rồ" của bạn bên trong chức năng đó ...
onetrickpony

Có lẽ khó hiểu từ ví dụ đơn giản hóa của tôi. Biến $ points được sử dụng trong suốt mẫu đó. Tôi muốn tính toán nó một lần và chuyển giá trị đó cho hàm gọi lại cho bộ lọc để thay đổi tiêu đề trang. Bộ lọc này được sử dụng trong Gói SEO All In One. Chạy tính toán nhiều lần là không mong muốn.
kingkool68

Sau đó, bạn nên đăng thêm mã nếu bạn muốn có một giải pháp không liên quan đến việc giới thiệu trạng thái toàn cầu (điều không bao giờ cần thiết).
onetrickpony

Đây là mã hoàn chỉnh trong một tệp mẫu. $scoređược tính bằng cách lặp qua một mảng các thứ và tăng một biến. pastebin.com/fkSXY04m
kingkool68

Câu trả lời:


10

Bạn có ít nhất hai tùy chọn:

  1. Toàn cầu hóa biến mong muốn và sau đó tham chiếu nó trong hàm gọi lại
  2. Bao bọc logic tính toán điểm số bằng một hàm, sau đó tham chiếu nó bên trong hàm gọi lại

Toàn cầu hóa biến

<?php
global $score;
$score = 42; //Some crazy calculation I don't want to repeat.

function add_score_to_title($title) {
    global $score;
    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');
?>

Kết thúc tính toán điểm

Nếu bạn chỉ cần tính toán điểm bên trong bộ lọc, hãy kéo logic vào chính cuộc gọi lại:

<?php
function add_score_to_title($title) {
    $score = 0;
    $questions = get_quiz_result_questions();
    $total_questions = 0;
    foreach( $questions as $question ) {
        $order = $question->order;

        if( $order >= 100 ) {
            break;
    }

    if( $question->correct == $_POST['Q'][$order] ) {
        $score++;
    }
    $total_questions++;

    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');
?>

Tốt hơn nữa, bạn có thể bao bọc tính toán điểm số của mình trong một chức năng của chính nó và sau đó gọi hàm đó trong hàm gọi lại của bạn:

<?php
function wpse48677_get_score() {
    $score = 0;
    $questions = get_quiz_result_questions();
    $total_questions = 0;
    foreach( $questions as $question ) {
    $order = $question->order;

    if( $order >= 100 ) {
        break;
    }

    if( $question->correct == $_POST['Q'][$order] ) {
        $score++;
    }
    $total_questions++;
    $output['score'] = $score;
    $output['total_questions'] = $total_questions;

    return $output;
}

function add_score_to_title($title) {

    $score_results = wpse48677_get_score();

    $score = $score_results['score'];

    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');
?>

Nếu bạn thấy bạn gặp vấn đề khi tham chiếu $_POSTđối tượng, bạn cũng có thể đăng ký biến truy vấn của mình và sau đó sử dụng get_query_var()nội bộ để lấy dữ liệu:

function add_score_query_vars( $query_vars ) {
    $query_vars[] = 'Q';

    return $query_vars;
}
add_filter( 'query_vars', 'add_score_query_vars' );

Với điều này tại chỗ, $_POST['Q']có thể được thay thế bằng get_query_var('Q').


Điều này không liên quan gì đến số lượng đối số được truyền cho hàm bởi application_filters ...
onetrickpony

Đã thử phương pháp số 1 mà bạn đề cập đến toàn cầu hóa biến. Nó không hoạt động. Tham số args được chấp nhận cũng không giúp tôi vì tôi không kiểm soát được biến nào được truyền cho hàm gọi lại.
kingkool68

Xin lỗi bạn đã đúng. Tôi đã tính toán $scoretrước và sau đó toàn cầu hóa nó. Không có gì ngạc nhiên khi nó không hoạt động. Cảm ơn bạn!
kingkool68

-1. Tùy chọn đầu tiên hiển thị một biến ở trạng thái toàn cầu, tùy chọn thứ 2 không hoạt động ...
onetrickpony

1
" Quả cầu là xấu xa "? Thật không Sau đó, toàn bộ mã WordPress đã được viết tốt hơn, vì nó phụ thuộc vào khá nhiều biến toàn cục .
Chip Bennett

3
function add_score_to_title($title = false) {
  static $score = false;

  if($score === false){
    // do calc
  }

  // plugin call (filter)   
  if($title !== false)
    return 'Quiz Results (' . $score . ') - ' . $title;

  // your call
  return $score;
}

Gọi hàm ở bất cứ đâu trong tập lệnh của bạn để lấy điểm, nó sẽ chỉ được tính một lần.

Một cách khác, sử dụng các hàm ẩn danh :

// do the calc
$score = 'xxx';

add_filter('aioseop_title_single', function($title) use($score){
  return 'Quiz Results (' . $score . ') - ' . $title;  
});

3
Các chức năng ẩn danh không nên được sử dụng trong add_filter()hoặc add_action()các cuộc gọi. Họ không thể được gỡ bỏ thông qua remove_function().
Chip Bennett

Bạn có nghĩa là remove_filter, chủ yếu được sử dụng để xóa các bộ lọc tích hợp, không phải các bộ lọc được thêm bởi các plugin / chủ đề ...
onetrickpony

1
Đúng; xin lỗi: remove_filter()remove_action(). Và không có lý do gì mà các bộ lọc Plugin / Theme không thể bị loại bỏ một cách hợp lý: ghi đè các biểu tượng kiểu của Plugin, Chủ đề con, v.v.
Chip Bennett

0

Ví dụ sau đây thấy biến $my_calculationtrong phạm vi toàn cầu, tuy nhiên từ bên trong hàm cục bộ của chúng ta, chúng ta cần khai báo global $my_calculationđể truy cập vào biến trong phạm vi toàn cục.

<?php 

    $my_calculation = 'result!';

    function my_function() {

        global $my_calculation;
        return $my_calculation;

    }

    add_filter( 'function_something_here', 'my_function');   

?>

Đây chỉ là một cách để đi về nó và nó có vẻ gọn gàng. Liệu nó có giúp hiệu quả với anh không?


Làm thế nào là khác với những gì anh ta đã có?
onetrickpony

Một lần ít tuyên bố "toàn cầu". Nhìn vào ví dụ thứ hai của anh ta, anh ta tuyên bố hả hê $ wp hai lần!
Adam

Nó cũng không hoạt động. Đây là điều đầu tiên tôi đã thử.
kingkool68

Bạn có thể printhoặc echokết quả của bạn để đảm bảo rằng chức năng của bạn thực sự hoạt động trước khi chuyển nó vào bộ lọc?
Adam

Giáo sư! Toàn cầu hóa $scorethực sự hoạt động. Tôi đã ủng hộ và thiết lập $scoređầu tiên sau đó toàn cầu hóa mà rõ ràng là không hoạt động. Làm theo cách phù hợp bằng cách toàn cầu hóa $scoretrước sau đó cho nó một giá trị hoạt động như mong đợi. Cảm ơn tất cả.
kingkool68
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.