जवाबों:
यह एक बहुत अच्छा सवाल है। यह प्लगइन एपीआई और सबसे अच्छा प्रोग्रामिंग प्रथाओं के अंधेरे दिल के लिए नीचे चला जाता है।
निम्नलिखित उत्तर के लिए मैंने कोड को पढ़ने में आसान के साथ समस्या का वर्णन करने के लिए एक सरल प्लगइन बनाया।
<?php # -*- coding: utf-8 -*-
/* Plugin Name: Anonymous OOP Action */
if ( ! class_exists( 'Anonymous_Object' ) )
{
/**
* Add some actions with randomized global identifiers.
*/
class Anonymous_Object
{
public function __construct()
{
add_action( 'wp_footer', array ( $this, 'print_message_1' ), 5 );
add_action( 'wp_footer', array ( $this, 'print_message_2' ), 5 );
add_action( 'wp_footer', array ( $this, 'print_message_3' ), 12 );
}
public function print_message_1()
{
print '<p>Kill me!</p>';
}
public function print_message_2()
{
print '<p>Me too!</p>';
}
public function print_message_3()
{
print '<p>Aaaand me!</p>';
}
}
// Good luck finding me!
new Anonymous_Object;
}
अब हम इसे देखते हैं:
वर्डप्रेस को फ़िल्टर के लिए एक नाम की आवश्यकता होती है । हमने एक प्रदान नहीं किया, इसलिए वर्डप्रेस कॉल _wp_filter_build_unique_id()
और एक बनाता है। यह नाम अनुमानित नहीं है क्योंकि यह उपयोग करता है spl_object_hash()
।
अगर हम इस var_export()
पर दौड़ते हैं तो हमें $GLOBALS['wp_filter'][ 'wp_footer' ]
ऐसा कुछ मिलता है:
array (
5 =>
array (
'000000002296220e0000000013735e2bprint_message_1' =>
array (
'function' =>
array (
0 =>
Anonymous_Object::__set_state(array(
)),
1 => 'print_message_1',
),
'accepted_args' => 1,
),
'000000002296220e0000000013735e2bprint_message_2' =>
array (
'function' =>
array (
0 =>
Anonymous_Object::__set_state(array(
)),
1 => 'print_message_2',
),
'accepted_args' => 1,
),
),
12 =>
array (
'000000002296220e0000000013735e2bprint_message_3' =>
array (
'function' =>
array (
0 =>
Anonymous_Object::__set_state(array(
)),
1 => 'print_message_3',
),
'accepted_args' => 1,
),
),
20 =>
array (
'wp_print_footer_scripts' =>
array (
'function' => 'wp_print_footer_scripts',
'accepted_args' => 1,
),
),
1000 =>
array (
'wp_admin_bar_render' =>
array (
'function' => 'wp_admin_bar_render',
'accepted_args' => 1,
),
),
)
हमारी बुरी कार्रवाई को खोजने और हटाने के लिए हमें हुक के लिए संबंधित फ़िल्टर के माध्यम से जाना होगा (एक क्रिया सिर्फ एक बहुत ही सरल फिल्टर है), जांचें कि क्या यह एक सरणी है और यदि वस्तु वर्ग का एक उदाहरण है। फिर हम प्राथमिकता लेते हैं और फ़िल्टर को हटाते हैं, बिना वास्तविक पहचानकर्ता को देखे ।
ठीक है, चलो इसे एक समारोह में रखें:
if ( ! function_exists( 'remove_anonymous_object_filter' ) )
{
/**
* Remove an anonymous object filter.
*
* @param string $tag Hook name.
* @param string $class Class name
* @param string $method Method name
* @return void
*/
function remove_anonymous_object_filter( $tag, $class, $method )
{
$filters = $GLOBALS['wp_filter'][ $tag ];
if ( empty ( $filters ) )
{
return;
}
foreach ( $filters as $priority => $filter )
{
foreach ( $filter as $identifier => $function )
{
if ( is_array( $function)
and is_a( $function['function'][0], $class )
and $method === $function['function'][1]
)
{
remove_filter(
$tag,
array ( $function['function'][0], $method ),
$priority
);
}
}
}
}
}
हम इस फ़ंक्शन को कब कहते हैं? जब मूल वस्तु बनाई जाती है तो निश्चित रूप से जानने का कोई तरीका नहीं होता है। शायद कभी पहले 'plugins_loaded'
? शायद बाद में?
हम उसी हुक का उपयोग करते हैं जो वस्तु से जुड़ा हुआ है और प्राथमिकता के साथ बहुत जल्दी में कूद जाता है 0
। यह वास्तव में सुनिश्चित करने का एकमात्र तरीका है। यहां बताया गया है कि हम इस विधि को कैसे निकालेंगे print_message_3()
:
add_action( 'wp_footer', 'kill_anonymous_example', 0 );
function kill_anonymous_example()
{
remove_anonymous_object_filter(
'wp_footer',
'Anonymous_Object',
'print_message_3'
);
}
नतीजा:
और यह आपके प्रश्न से कार्रवाई को दूर करना चाहिए (परीक्षण नहीं):
add_action( 'comments_array', 'kill_FbComments', 0 );
function kill_FbComments()
{
remove_anonymous_object_filter(
'comments_array',
'SEOFacebookComments',
'FbComments'
);
}
'plugins_loaded'
। इतना ही नहीं जब आपका प्लगइन WordPress द्वारा कॉल किया जाता है।plugins_loaded
जाता है जब कहा जाता है, जो वास्तव plugins_loaded
में है। बेशक, वर्ग उदाहरण अभी भी सुलभ होने की जरूरत है, संभवतः सिंगलटन पैटर्न के माध्यम से।
remove_action()
मुझे यकीन नहीं है, लेकिन आप एक सिंगलटन का उपयोग करने की कोशिश कर सकते हैं।
आपको अपनी कक्षा की स्थिर संपत्ति में ऑब्जेक्ट संदर्भ को संग्रहीत करना होगा और फिर उस स्थिर चर को स्थिर विधि से वापस करना होगा। कुछ इस तरह:
class MyClass{
private static $ref;
function MyClass(){
$ref = &$this;
}
public static function getReference(){
return self::$ref;
}
}
जब तक आप वस्तु को जानते हैं (और आप PHP 5.2 या उच्चतर का उपयोग करते हैं - वर्तमान स्थिर PHP संस्करण 5.5 है, 5.4 अभी भी समर्थित है, 5.3 जीवन का अंत है), तो आप इसे remove_filter()
विधि के साथ हटा सकते हैं । आपको बस याद रखने की ज़रूरत है कि वस्तु, विधि-नाम और प्राथमिकता (यदि उपयोग की जाती है):
remove_filter('comment_array', [$this, 'FbComments']);
हालाँकि आप अपने कोड में थोड़ी गलती करते हैं। एम्परसैंड के $this
साथ उपसर्ग न करें &
, जो PHP 4 (!) में आवश्यक था और यह लंबे समय से अतिदेय है। यह आपके हुक समस्याग्रस्त से निपटने को प्रस्तुत कर सकता है, इसलिए बस इसे रास्ते से बाहर छोड़ दें:
add_filter('comments_array', [$this, 'FbComments]));
और बस।
$this
बाहर (किसी अन्य प्लगइन / थीम) से कोई पहुंच नहीं है ।
&
अपने से&$this
, यह एक PHP 4 बात है