ফিল্টার এবং ক্রিয়া কার্যের জন্য একটি পরামিতি পাস করা


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

ডিফল্টরূপে এটি সম্ভব নয়। আপনি যদি এটি ওওপি উপায়ে করেন তবে কার্যকারিতা রয়েছে।
আপনি যে মানগুলি পরে ব্যবহার করতে চান তা সঞ্চয় করতে আপনি একটি শ্রেণি তৈরি করতে পারেন।

উদাহরণ:

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

আউটপুট:

এখানে চিত্র বর্ণনা লিখুন

চাবিকাঠি পুনর্ব্যাবহার্যোগ্যতা ছেলে তুমি ক্লাসে (এবং আমাদের জন্য দৃষ্টান্তস্বরূপ ফাংশনে) পুনরায় ব্যবহার করতে পারেন।

পিএইচপি 5.3+

আপনি যদি পিএইচপি সংস্করণ 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
ডাব্লুপি কোর এর অভ্যন্তরীণ সমাধানের সমাধান হওয়া উচিত এমন সমস্যার মানসম্পন্ন উত্তরের জন্য আপনি কেবল একটি আপ-ভোট পান না , পিএইচপি 5.3+ ক্লোজার উদাহরণ সহ আপনার উত্তরটি আপডেট করার জন্য আপনি পাঁচ মাস পরে ফিরে আসার জন্য একটি পান।
আদম

1
দুর্দান্ত উত্তর! তবে পরে এই বেনাম ফাংশন দ্বারা নির্মিত এই ফিল্টারটি সরিয়ে ফেলতে আমি কীভাবে পারি?
ভিনিসিয়াস টাভারেস

2
পছন্দ করেছেন আপনি এটি ব্যবহার করার আগে চিন্তা করুন। :)
ফুসিয়া

5
তবে খেয়াল করুন যে আপনি যদি কোনও বেনামে বেনামে ফাংশনটি সংরক্ষণ করেন (যেমন $func = function() use ( $param1 ) { $param1; };এবং add_action( $func, 11);) তবে আপনি এটি মুছে ফেলতে পারেনremove_action( $func, 11 );
Bonger

1
তবে আপনি বিশ্বের কাছে প্রকাশিত হচ্ছেন এমন প্লাগইন বা থিমগুলিতে বেনাম ফাংশন ব্যবহার করা ভাল নয় (আপনি এগুলি আপনার নিজের প্রকল্পে ব্যবহার করতে পারেন)। এটির সাথে সমস্যা হ'ল আপনি এগুলি ছুঁড়ে ফেলতে পারবেন না। আপনি যেদিকে যাবার সিদ্ধান্ত নিয়েছেন তা পরে আনহুক-সক্ষম হওয়া উচিত।
মুইইওয়া মোসা ইকোমি

1

প্রয়োজনীয় আর্গুমেন্টগুলি দিয়ে একটি ফাংশন তৈরি করুন যা কোনও ফাংশন দেয়। এই ফাংশনটি (বেনামে ফাংশন, যা ক্লোজার নামেও পরিচিত) ডাব্লুপি হুককে দিন।

ওয়ার্ডপ্রেস ব্যাকএন্ডে প্রশাসকের বিজ্ঞপ্তির জন্য এখানে দেখানো হয়েছে।

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

পিএইচপি বেনামে ফাংশন ব্যবহার করুন :

$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

আমি জানি সময় অতিবাহিত হয়েছে, তবে আমার নিজের পরামিতিটি পাস করতে আমার কিছুটা সমস্যা হয়েছিল যতক্ষণ না দেখা পেলাম যে অ্যাড_ফিল্টারটির 4 র্থ প্যারামিটারটি পরিবর্তন করার সামগ্রী সহ উত্তীর্ণ প্যারামিটারগুলির সংখ্যা । সুতরাং আপনি যদি 1 টি অতিরিক্ত পরামিতি পাস করেন তবে আপনার ক্ষেত্রে নম্বরটি 2 নয় 1 হবে

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

এবং ব্যবহার

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

1

ডাব্লু ফিল্টার এবং কাজের আর্গুমেন্ট যাই হোক না কেন সংখ্যা ক্ষণস্থায়ী, সঠিক সত্যিই ছোট এবং সবচেয়ে কার্যকর উপায় @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 );

এটি রেজিস্ট্রেশন থেকে কলব্যাকে তথ্য দেয় না। এটি কেবলমাত্র কতগুলি পরামিতি কলব্যাক গ্রহণ করতে পারে তা বলে।
ফুসিয়া

@ ফুক্সিয়া, আপনি কি কোনও সাধারণ পরিবর্তন প্রস্তাব করতে পারেন যাতে তথ্যটি পাস হয়? কেউ কি পরের মানগুলিকে অনুসরণ করবে 3?
শেরিলহোমান

0

আপনি সর্বদা গ্লোবাল ব্যবহার করতে পারবেন না?

  global $my_param;


@ cjbj আসলে তা করে। প্রশ্নটি হ'ল পরামিতিগুলি অ্যাড_ফিল্টার বা অ্যাড_অ্যাকশনটিতে থাকা "ফাংশন" এ দেওয়া যেতে পারে। এটি অনুমান হওয়া সত্ত্বেও ব্যবহারকারী এটির যোগ-ফিল্টার বা অ্যাড_অ্যাকশন ফাংশনে নিজেই এটি পাস করতে চান কিনা তা স্পষ্ট ছিল না। :)
সামজকো

0

সরাসরি কোনও ফাংশন কল করার পরেও এটি আরও মার্জিত উপায়ে করুন: একটি বেনাম ফাংশন কলব্যাক হিসাবে পাস করুন।

উদাহরণ স্বরূপ:

শিরোনাম, বিষয়বস্তু এবং আমার পোস্টগুলি থেকে উদ্ধৃত অংশ অনুবাদ করার জন্য আমার একক ফাংশন রয়েছে। সুতরাং, আমাকে এই মূল ফাংশনটি পাস করতে হবে কিছু আর্গুমেন্ট যা বলছে calling

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

তারপরে আমার_ কনটেন্ট_ফিল্টার () কেবল_আপনি কল করতে পারে () এটি চাইলে যে কোনও যুক্তি দিয়ে যায়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.