필터 및 동작 함수에 매개 변수 전달


52

add_filter또는 의 함수에 내 매개 변수를 전달하는 방법 add_action입니다. 예를 들어 다음 코드를 살펴보십시오.

function my_content($content, $my_param)
{
do something...
using $my_param here ...
return $content;
}
add_filter('the_content', 'my_content', 10, 1);

내 매개 변수를 전달할 수 있습니까? 같은 :

add_filter('the_content', 'my_content($my_param)', 10, 1)

또는

add_filter('the_content', 'my_content', 10, 1, $my_param)

답변:


77

기본적으로 이것은 불가능합니다. OOP 방식으로 수행하면 해결 방법이 있습니다.
나중에 사용하려는 값을 저장하는 클래스를 만들 수 있습니다.

예:

/**
 * Stores a value and calls any existing function with this value.
 */
class WPSE_Filter_Storage
{
    /**
     * Filled by __construct(). Used by __call().
     *
     * @type mixed Any type you need.
     */
    private $values;

    /**
     * Stores the values for later use.
     *
     * @param  mixed $values
     */
    public function __construct( $values )
    {
        $this->values = $values;
    }

    /**
     * Catches all function calls except __construct().
     *
     * Be aware: Even if the function is called with just one string as an
     * argument it will be sent as an array.
     *
     * @param  string $callback Function name
     * @param  array  $arguments
     * @return mixed
     * @throws InvalidArgumentException
     */
    public function __call( $callback, $arguments )
    {
        if ( is_callable( $callback ) )
            return call_user_func( $callback, $arguments, $this->values );

        // Wrong function called.
        throw new InvalidArgumentException(
            sprintf( 'File: %1$s<br>Line %2$d<br>Not callable: %3$s',
                __FILE__, __LINE__, print_r( $callback, TRUE )
            )
        );
    }
}

이제 원하는 함수로 클래스를 호출 할 수 있습니다. 함수가 어딘가에 있으면 저장된 매개 변수로 호출됩니다.

데모 기능을 만들어 보자…

/**
 * Filter function.
 * @param  array $content
 * @param  array $numbers
 * @return string
 */
function wpse_45901_add_numbers( $args, $numbers )
{
    $content = $args[0];
    return $content . '<p>' . implode( ', ', $numbers ) . '</p>';
}

… 한 번만 사용하십시오…

add_filter(
    'the_content',
    array (
        new WPSE_Filter_Storage( array ( 1, 3, 5 ) ),
        'wpse_45901_add_numbers'
    )
);

… 다시 한번 …

add_filter(
    'the_content',
    array (
        new WPSE_Filter_Storage( array ( 2, 4, 6 ) ),
        'wpse_45901_add_numbers'
    )
);

산출:

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

핵심은 재사용 성입니다 . 클래스를 재사용 할 수 있습니다 (이 예제에서도 함수).

PHP 5.3 이상

PHP 버전 5.3 이상 을 사용하면 더 쉽게 닫을 수 있습니다.

$param1 = '<p>This works!</p>';
$param2 = 'This works too!';

add_action( 'wp_footer', function() use ( $param1 ) {
        echo $param1;
    }, 11 
);
add_filter( 'the_content', function( $content ) use ( $param2 ) {
        return t5_param_test( $content, $param2 );
    }, 12
);

/**
 * Add a string to post content
 *
 * @param  string $content
 * @param  string $string This is $param2 in our example.
 * @return string
 */
function t5_param_test( $content, $string )
{
    return "$content <p><b>$string</b></p>";
}

단점은 클로저에 대한 단위 테스트를 작성할 수 없다는 것입니다. 


17
WP 코어 내에 솔루션이 내장되어 있어야 하는 문제에 대한 품질 답변에 대한 투표를 할뿐만 아니라 5 개월 후에 다시 PHP 5.3+ 클로저 예제로 답변을 업데이트 할 수 있습니다.
Adam

1
훌륭한 답변! 그러나 나중에이 익명 함수로 작성된이 필터를 제거하려면 어떻게해야합니까?
Vinicius Tavares

2
@ViniciusTavares 당신은 할 수 없습니다. 사용하기 전에 생각하십시오. :)
fuxia

5
익명 함수를 변수 (예 : $func = function() use ( $param1 ) { $param1; };add_action( $func, 11);)에 저장하면 다음을 통해 제거 할 수 있습니다.remove_action( $func, 11 );
bonger

1
그러나 전 세계에 공개하는 플러그인이나 테마에는 익명 함수를 사용하지 않는 것이 좋습니다 (자신의 프로젝트에서 사용할 수 있음). 이것의 문제는 당신이 그것들을 풀 수 없다는 것입니다. 당신이 가기로 결정한 접근법은 나중에 훅을 풀 수 있어야합니다.
Mueyiwa Moses Ikomi

1

함수를 리턴하는 필수 인수로 함수를 작성하십시오. 이 함수 (익명 함수, 클로저라고도 함)를 wp hook에 전달하십시오.

워드 프레스 백엔드의 관리자 통지를 위해 여기에 표시됩니다.

public function admin_notice_func( $message = '')
{
$class = 'error';
    $output = sprintf('<div class="%s"><p>%s</p></div>',$class, $message);
    $func = function() use($output) { print $output; };
    return $func;
}
$func = admin_notice_func('Message');
add_action('admin_notices', $func);

1

PHP 익명 함수 사용 :

$my_param = 'my theme name';
add_filter('the_content', function ($content) use ($my_param) {
    //$my_param is available for you now
    if (is_page()) {
        $content = $my_param . ':<br>' . $content;
    }
    return $content;
}, 10, 1);

1

시간이 지났다는 것을 알고 있지만 add_filter의 4 번째 매개 변수 가 변경할 내용을 포함 하여 전달 된 매개 변수의 수임을 알 때까지 자체 매개 변수를 전달하는 데 문제가있었습니다 . 따라서 1 개의 추가 매개 변수를 전달하면 숫자는 1이 아닌 2 가되어야합니다.

add_filter('the_content', 'my_content', 10, 2, $my_param)

그리고 사용

function my_content($content, $my_param) {...}

1

WP 필터와 액션에 인수 어떤 수를 전달하는 올바른 정말 짧고 가장 효율적인 방법은 @Wesam Alalem에서입니다 여기 폐쇄를 사용합니다.

익명 처리와 실제 수행 방법을 분리하여 훨씬 명확하고 유연하게 만들 수 있다고 덧붙였습니다. 이를 위해 다음과 같이 클로저에서 메소드를 호출하십시오 (@Wesam Alalem 답변의 수정 된 예).

이런 식으로 실제 행위자를 호출하는 데 사용하는 클로저 외부에서 어휘 적으로 원하는만큼 길거나 복잡한 논리를 작성할 수 있습니다.

// ... inside some class

private function myMethod() {
    $my_param = 'my theme name';
    add_filter('the_content', function ($content) use ($my_param) {
        // This is the anonymous closure that allows to pass 
        // whatever number of parameters you want via 'use' keyword.
        // This is just oneliner.
        // $my_param is available for you now via 'use' keyword above
        return $this->doThings($content, $my_param);
    }, 10, 2);
}

private function doThings($content, $my_param) {
    // Call here some other method to do some more things
    // however complicated you want.
    $morethings = '';
    if ($content = 'some more things') {
        $morethings = (new MoreClass())->get();
    }
    return $my_param . ':<br>' . $content . $morethings;
}

0

당신이 당신의 자신의 후크를 만드는 경우, 여기 예제입니다.

// lets say we have three parameters  [ https://codex.wordpress.org/Function_Reference/add_filter ]
add_filter( 'filter_name', 'my_func', 10, 3 );
my_func( $first, $second, $third ) {
  // code
}

그런 다음 후크를 구현하십시오.

// [ https://codex.wordpress.org/Function_Reference/apply_filters ]
echo apply_filters( 'filter_name', $first, $second, $third );

이것은 등록에서 콜백으로 정보를 전달하지 않습니다. 콜백이 수용 할 수있는 매개 변수 수를 나타냅니다.
fuxia

@ fuxia, 정보가 전달되도록 간단한 변경을 제안 할 수 있습니까? ? 다음에 매개 변수 값을 붙일 것 3입니까?
SherylHohman

0

항상 글로벌을 사용할 수 있습니까?

  global $my_param;

이것은 질문에 대한 답변을 제공하지 않습니다. 평판 이 충분 하면 모든 게시물댓글 수 있습니다 . 대신 asker의 설명이 필요없는 답변을 제공하십시오 . - 리뷰에서
cjbj

@cjbj 실제로 그렇습니다. 문제는 매개 변수가 add_filter 또는 add_action에있는 "function"으로 전달 될 수 있다는 것입니다. 사용자가 add_filter 또는 add_action 함수 자체에서 전달한다고 가정했는지는 확실하지 않습니다. :)
samjco

0

함수를 직접 호출 함에도 불구하고보다 우아한 방식으로이 작업을 수행하십시오 . 익명 함수를 콜백으로 전달하십시오.

예를 들면 다음과 같습니다.

게시물의 제목, 내용 및 발췌문을 번역하는 단일 기능이 있습니다. 그래서 나는이 주요 기능에 누가 전화하고 있는지에 대한 몇 가지 주장을 전달해야합니다.

add_filter( 'the_title', function( $text ) { 
    return translate_text( $text, 'title', 'pl' );
});

add_filter( 'the_content', function( $text ) { 
    return translate_text( $text, 'content', 'pl' );
});

add_filter( 'the_excerpt', function( $text ) { 
    return translate_text( $text, 'excerpt', 'pl' );
});

따라서 주 함수 translate_text는 익명 함수를 콜백으로 전달했기 때문에 원하는만큼 많은 매개 변수를받습니다.


-1

나는 똑같이하고 싶었지만 불가능했기 때문에 간단한 해결 방법은 다음과 같은 다른 함수를 호출하는 것 같습니다. add_filter('the_content', 'my_content_filter', 10, 1);

그러면 my_content_filter ()는 원하는 인수를 전달하여 my_content ()를 호출 할 수 있습니다.

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