फ़िल्टर और कार्रवाई कार्यों के लिए एक पैरामीटर पास करना


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)

जवाबों:


78

डिफ़ॉल्ट रूप से यह संभव नहीं है। यदि आप इसे 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 कोर के भीतर एक समाधान में होना चाहिए , आपको PHP 5.3+ क्लोजर उदाहरण के साथ अपने उत्तर को अपडेट करने के लिए पांच महीने बाद वापस आने के लिए भी मिलता है।
एडम

1
बहुत बढ़िया जवाब! लेकिन मैं बाद में इस अनाम फ़ंक्शन द्वारा बनाए गए फ़िल्टर को कैसे हटा सकता हूं?
विनीसियस तवारेस

2
@ViniciusTavares आप नहीं कर सकते। उपयोग करने से पहले सोचें। :)
FUXIA

5
ध्यान दें कि यदि आप अनाम फ़ंक्शन को एक चर (जैसे $func = function() use ( $param1 ) { $param1; };और add_action( $func, 11);) में सहेजते हैं, तो आप इसे माध्यम से निकाल सकते हैंremove_action( $func, 11 );
बोंगर

1
लेकिन प्लगइन्स या थीम पर अनाम फ़ंक्शंस का उपयोग करने की सलाह नहीं दी जाती है जो आप दुनिया को जारी कर रहे हैं (आप उन्हें अपने प्रोजेक्ट्स पर उपयोग कर सकते हैं)। इसके साथ समस्या यह है कि आप उन्हें अनहुक नहीं कर पाएंगे। आप जिस भी दृष्टिकोण के साथ जाने का निर्णय लेते हैं, उसे बाद में अनसुना कर दिया जाना चाहिए।
मुयेइवा मूसा इकोमी

1

फ़ंक्शन के साथ आवश्यक फ़ंक्शन बनाएँ जो एक फ़ंक्शन देता है। इस फ़ंक्शन (अनाम फ़ंक्शन, जिसे क्लोज़र के रूप में भी जाना जाता है) को wp हुक में पास करें।

WordPress बैकएंड में एक व्यवस्थापक सूचना के लिए यहां दिखाया गया है।

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

मुझे पता है कि समय बीत चुका है, लेकिन मुझे अपना पैरामीटर पारित करने में कुछ समस्या थी जब तक मैंने पाया कि add_filter में 4th पैरामीटर परिवर्तन किए गए सामग्री सहित पारित मापदंडों की संख्या है । इसलिए यदि आप 1 अतिरिक्त पैरामीटर पास करते हैं, तो संख्या आपके मामले में 2 और 1 नहीं होनी चाहिए

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

और उपयोग कर रहा है

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

1

WP फ़िल्टर और कार्यों के लिए जितने भी तर्क दिए जा रहे हैं, उनका सही, वास्तव में संक्षिप्त और सबसे कुशल तरीका , यहाँ पर बंदे का उपयोग करता है।

मैं केवल इतना ही जोड़ूंगा कि आप वास्तविक बंद करने वाले तरीके को गुमनाम बंद से अलग करके इसे और भी अधिक लचीला बना सकते हैं। इसके लिए आप बस क्लोजर से विधि को इस प्रकार कहते हैं (@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?
शेरलहोमन

0

आप हमेशा वैश्विक उपयोग कर सकते हैं क्या आप नहीं कर सकते हैं?

  global $my_param;

यह प्रश्न का उत्तर प्रदान नहीं करता है। एक बार आपके पास पर्याप्त प्रतिष्ठा होने पर आप किसी भी पोस्ट पर टिप्पणी करने में सक्षम होंगे ; इसके बजाय, ऐसे उत्तर प्रदान करें जिन्हें पूछने वाले से स्पष्टीकरण की आवश्यकता न हो । - रिव्यू से
cjbj

@cjbj वास्तव में यह करता है। सवाल यह है कि पैरामीटर "फ़ंक्शन" में जोड़े जा सकते हैं जो कि add_filter या add_action में है। यह स्पष्ट नहीं था कि यदि उपयोगकर्ता इसे 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 () किसी भी तर्क को पारित कर सकता है जिसे वह चाहता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.