필터 내에서 단축 코드의 입력 값을 얻는 방법은 무엇입니까?


9

필터에서 사용하는 함수 내에서 단축 코드의 입력 값을 얻으려고하는데 성공하지 못한 것 같습니다. 여기 내가 한 일이 있습니다.

function my_shortcode_function($atts){
    $value = $atts['id'];
    function filter_value(){
        echo $value;
    }
    add_filter('posts_where','filter_value');
}
add_shortcode('my-shortcode','my_shortcode_function');

이제 변수 범위로 인해 $valueinside filter_value()사용 $GLOBALS['value']이 작동하지 않지만 사용조차도 작동하지 않습니다.

나는 $value = $atts['id']내부 에서도 사용하려고 filter_value();했지만 성공하지 못했습니다.

단축 코드를 어떻게 사용 [my-shortcode id='123']하고 123 값을 필터에 전달할 수 있습니까?

감사.

답변:


7

전역 변수를 사용하면 작동합니다. 데모는 다음과 같습니다.

function wpse_shortcode_function( $atts ){
    // User provided values are stored in $atts.
    // Default values are passed to shortcode_atts() below.
    // Merged values are stored in the $a array.
    $a = shortcode_atts( [
                'id'   => false,
    ], $atts );

    // Set global variable $value using value of shortcode's id attribute.
    $GLOBALS['value'] = $a['id'];

    // Add our filter and do a query.
    add_filter( 'posts_where', 'wpse_filter_value' );

    $my_query = new WP_Query( [
        'p' => $GLOBALS['value'],
    ] );

    if ( $my_query->have_posts() ) {
        while ( $my_query->have_posts() ) {
            $my_query->the_post();
            the_title( '<h1>', '</h1>');
        }
        wp_reset_postdata();
    }

    // Disable the filter.
    remove_filter( 'posts_where', 'wpse_filter_value' );
}
add_shortcode( 'my-shortcode', 'wpse_shortcode_function' );

function wpse_filter_value( $where ){
    // $GLOBALS['value'] is accessible here.

    // exit ( print_r( $GLOBALS['value'] ) );

    return $where;
}

참고로, 다른 함수 내에서 함수를 선언하는 것은 좋은 습관이 아닙니다 .


이것은 실제로 이상합니다. 사용하여 값을 설정 한 $GLOBALS['value'] = some value다음 호출하면 $GLOBALS['value']작동하지만 작동하지 않지만 값 $value = some value을 사용하여 호출하면 $GLOBALS['value']작동하지 않지만 PHP 매뉴얼에 따라 작동합니다.
— 잭 요한슨

값으로 초기화하기 전에 $value전역 범위 로 설정 해야합니다 global $value;. 예 global $value; $value = $a['id']; 를 들어 필터에서 할 수 global $value; echo $value;있습니까?
— Dave Romsey

네 고마워요 나는 이것을 매뉴얼 에서 읽고 있었고 , 첫 번째 예에서는 값이 직접 정의되었습니다. 직접 사용할 수 있도록 모든 함수 외부에서 정의해야 $GLOBALS['value'];합니까?
— 잭 요한슨

2
멋있는. 다행 이네 해당 문서의 첫 번째 예에서 변수는 함수 외부와 전역 범위 내에서 선언됩니다. 따라서 global키워드가 필요 하지 않습니다. 이 예에서는 함수 범위 내에서 작업 해 왔으므로 global키워드가 필요합니다.
— Dave Romsey

1
필터는 우리의 친구입니다! :-) 도움이 더 필요한 경우 일부 열성적인 답변자가 귀하의 질문에 대답 할 것입니다.
— Dave Romsey

7

몇 가지 해결 방법이 있습니다.

접근법 # 1

클래스 코드 사이에 주어진 값을 전달할 수 있도록 클래스posts_where 에서 단축 코드의 정의와 필터의 콜백을 래핑 할 수 있습니다 (예 : 전용 변수).

접근법 # 2

또 다른 방법은 WP_Query단축 코드의 콜백 내 에서 값을 입력으로 전달하는 것입니다 .

$query = new WP_Query ( [ 'wpse_value' => 5, ... ] );

그런 다음 posts_where 필터 내에서 액세스 할 수 있습니다.

add_filter( 'posts_where', function( $where, \WP_Query $query )
{

    if( $value = $query->get( 'wpse_value' ) )
    {
        // can use $value here
    }

    return $where;

}, 10, 2 );

접근법 # 3

... 또는 익명 함수를 변수에 할당하여 나중에 콜백을 제거 할 수 있도록 @the_dramatist 의 예제 를 조정할 수도 있습니다 .

function my_shortcode_function( $atts, $content )
{
    // shortcode_atts stuff here

    $value = 5; // just an example  

    // Add a filter's callback
    add_filter( 'posts_where',  $callback = function( $where ) use ( $value ) {
        // $value accessible here
        return $where;
    } );

    // WP_Query stuff here and setup $out

    // Remove the filter's callback
    remove_filter( 'posts_where', $callback );

    return $out;
}

add_shortcode( 'my-shortcode', 'my_shortcode_function' );   

use 키워드와 함께 익명 함수를 변수에 할당하는 방법에 대해서는 PHP 문서 를 확인하십시오 .

추신 : 익명 필터의 콜백을 쉽게 제거 할 수 있도록 @gmazzap의 트릭을 할당하는이 변수에 대해 처음 알게 된 것 같습니다.

그것이 도움이되기를 바랍니다!


언제나처럼 감사하고 친절하고 정확한 답변. 전역 고유 변수를 사용하는 것보다 함수 내에 함수를 정의하는 것이 좋습니다? 그렇다면, 이유를 말씀해 주시겠습니까?
— Jack Johansson

해당 함수를 재사용해야하고 다른 함수의 범위 내에 갇혀 있고 다른 개발자가 익명 콜백으로 필터를 건너 뛰기가 더 어려울 경우 이는 좋은 생각이 아닙니다. 따라서 wp.org 저장소의 공식 플러그인으로 다른 개발자가 가능한 한 쉽게 필터를 제거 할 수 있도록 노력할 것입니다. 접근하다. 플러그인 구조로 모퉁이에 들어가면 대체 구조를 사용할 수 있습니다. ;-)
— birgire

나는 당신의 세 번째 접근 방식으로 가고 있다고 생각합니다. 내 경우에는 효과가있는 것 같습니다. 건배!
— Jack Johansson

가장 적합한 것이 무엇이든 확실합니다. 나는 다시 쉽게 제거하기 위해 아무 함수없이 # 1 또는 # 2를 사용할 수 있습니다 ;-) @JackJohansson
— birgire

2
우리는 실제로 사용자 정의 인수와 그 값을 전달할 수 있습니다 WP_Query같은 다양한 필터를 통해 지정된 인스턴스 액세스를 대상으로 posts_where, pre_get_posts그리고 posts_clauses. 이것이 우리가 접근법 # 2에서하는 일입니다.
— birgire

4

PHPuse 키워드를 사용할 수 있습니다 . 따라서이 키워드 의 도움으로 함수 내부에 변수를 가져올 수 있습니다. 또한 익명 함수를 작성하여 코드를 줄일 수 있습니다. 그래서 모든 것이use

/**
 * How to get shorcode's input values inside a filter?
 *
 * @param $atts
 */
function my_shortcode_function($atts){
    $value = $atts['id'];
    add_filter('posts_where',function() use ( $value ){
        echo $value;
    });

}
add_shortcode('my-shortcode','my_shortcode_function');

희망이 도움이됩니다.


이것은 멋지지만 익명의 기능은 풀기 어렵습니다.
— Dave Romsey

2
익명의 기능을 제거하는 것은 이제 질문에 대한 또 다른 답변에서 @birgire에 의해 다루어졌습니다. 멋있는!
— Dave Romsey 님이

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.