필터 / 액션에 외부 변수를 전달하는 방법


11

타사 플러그인에서 제공하는 필터에 사용자 정의 데이터를 전달해야한다는 것을 알았습니다. 내가 본 모든 방법은 정말 복잡하고 머리를 감쌀 수 없습니다.

이 예제를 보자 :

$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');

$score변수를 add_score_to_title()어떻게 전달할 수 있습니까?

내가 한 일은 전역 변수에 변수를 추가하는 것이 었습니다 $wp. 그래서 당신은 이것으로 끝납니다 :

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');

더러운? 아마도. 단순한? 예! 이 기술의 단점은 무엇입니까? 토론하십시오.

업데이트 여기에 문제의 완전한 코드가 있습니다-> http://pastebin.com/fkSXY04m


그 함수 안에서 "미친 계산"을하기 만하면됩니다.
onetrickpony

간단한 예제에서 이해하기 어려울 것입니다. $ score 변수는 해당 템플릿 전체에서 사용됩니다. 한 번 계산하고 해당 값을 페이지 제목을 변경하는 필터의 콜백 인 함수에 전달하려고합니다. 이 필터는 올인원 SEO 팩에 사용됩니다. 계산을 여러 번 실행하는 것은 바람직하지 않습니다.
kingkool68

그런 다음 전역 상태를 도입하지 않는 솔루션을 얻으려면 더 많은 코드를 게시해야합니다 (필요하지 않아야 함).
onetrickpony

템플릿 파일의 전체 코드는 다음과 같습니다. $score사물 배열을 반복하고 변수를 증가시켜 계산합니다. pastebin.com/fkSXY04m
kingkool68

답변:


10

최소한 두 가지 옵션이 있습니다.

  1. 원하는 변수를 전역 화 한 다음 콜백 내에서 참조하십시오
  2. 점수 계산 논리를 함수로 감싸고 콜백 내에서 참조하십시오.

변수를 세계화

<?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');
?>

점수 계산 랩

필터 내부 에서 점수 계산 만 필요한 경우 로직을 콜백 자체로 가져옵니다.

<?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');
?>

더 좋은 점은 점수 계산을 자체 함수로 래핑 한 다음 콜백 내에서 해당 함수를 호출하는 것입니다.

<?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');
?>

$_POST객체를 참조하는 데 문제가있는 경우 쿼리 변수를 등록한 다음 get_query_var()내부적으로 사용 하여 데이터를 가져올 수 있습니다.

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

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

이를 사용하여 $_POST['Q']로 교체 할 수 있습니다 get_query_var('Q').


apply_filters에 의해 함수에 전달 된 인수의 수와는 아무런 관련이 없습니다.
onetrickpony

시도한 방법 # 1에서는 변수를 세계화하는 것에 대해 언급했습니다. 작동하지 않습니다. 수락 된 args 매개 변수는 콜백 함수에 전달되는 변수를 제어 할 수 없으므로 도움이되지 않습니다.
kingkool68

네가 옳아 서 미안해 $score먼저 계산 한 다음 세계화했습니다. 그것이 작동하지 않는 것은 당연합니다. 감사합니다!
kingkool68

-1. 첫 번째 옵션은 전역 상태에서 변수를 노출하고, 두 번째 옵션은 작동하지 않습니다 ...
onetrickpony

1
" 글로벌은 악하다 "? 정말요 ? 그런 다음 전체 WordPress 코드를 작성하는 것이 더 좋았 습니다 . 전역 변수에 의존 하기 때문 입니다.
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;
}

점수를 얻으려면 스크립트의 아무 곳이나 함수를 호출하면 한 번만 계산됩니다.

익명 함수를 사용하는 다른 방법 :

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

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

3
익명 함수에서 사용할 수 없습니다 add_filter()또는 add_action()전화. 를 통해 제거 할 수 없습니다 remove_function().
Chip Bennett

플러그인 / 테마에 의해 추가 된 필터가 아니라 내장 필터를 제거하는 데 주로 사용되는 remove_filter를 의미합니다.
onetrickpony

1
예; 죄송합니다 : remove_filter()remove_action(). 그리고 플러그인 / 테마 필터가 합리적으로 제거 될 수없는 이유는 없습니다 : 플러그인 스타일 시트 대기열, 자식 테마 등을 무시하십시오.
Chip Bennett

0

다음 예제는 $my_calculation전역 범위에서 변수 를 확인하지만 로컬 함수 내 global $my_calculation에서 전역 범위에서 변수에 액세스하기 위해 선언해야합니다 .

<?php 

    $my_calculation = 'result!';

    function my_function() {

        global $my_calculation;
        return $my_calculation;

    }

    add_filter( 'function_something_here', 'my_function');   

?>

이것은 그것에 관한 한 가지 방법 일뿐이며 깔끔한 것처럼 보입니다. 이것이 당신을 위해 작동합니까?


이것이 이미 가지고있는 것과 어떻게 다른가?
onetrickpony

"글로벌"의 선언이 한 번 줄었다 그의 두 번째 예를 보면 gloabl $ wp를 두 번 선언합니다!
Adam

또한 작동하지 않습니다. 이것이 내가 시도한 첫 번째 것입니다.
kingkool68

당신은 할 수 있습니다 print또는 echo당신의 결과는 함수가 실제로 필터에 전달하기 전에 작동하는지 확인하기 위해?
Adam

죄송합니다! 세계화 $score는 실제로 작동합니다. 나는 $score분명히 작동하지 않는 세계화 된 다음 세계화했습니다. $score먼저 세계화하여 올바른 방법으로 가치를 부여하면 예상대로 작동합니다. 모두 감사합니다.
kingkool68
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.