উত্তর:
এটা খুব ভাল প্রশ্ন। এটি প্লাগইন এপিআই এবং সেরা প্রোগ্রামিং অনুশীলনের অন্ধকারে চলে যায়।
নিম্নলিখিত উত্তরের জন্য আমি কোড পড়তে সহজ সঙ্গে সমস্যাটি বর্ণনা করার জন্য একটি সাধারণ প্লাগইন তৈরি করেছি।
<?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'
। যখন আপনার প্লাগইনটি ওয়ার্ডপ্রেস দ্বারা ডাকা হয় তখনই নয়।plugins_loaded
ডাকা হওয়ার সময় সেগুলি আসলে যুক্ত করা হয়েছিল , যা ঠিক সেটির plugins_loaded
জন্য। অবশ্যই, ক্লাস উদাহরণটি এখনও অ্যাক্সেসযোগ্য হওয়া দরকার, সম্ভবত সিঙ্গলটন প্যাটার্নের মাধ্যমে।
remove_action()
আমি নিশ্চিত নই তবে আপনি একটি সিঙ্গলটন ব্যবহার করে দেখতে পারেন।
আপনাকে অবশ্যই অবশ্যই নিজের শ্রেণীর স্থিতিশীল সম্পত্তিতে অবজেক্টের রেফারেন্স সংরক্ষণ করতে হবে এবং তারপরে স্থির পদ্ধতি থেকে স্ট্যাটিক ভেরিয়েবলটি ফিরিয়ে আনতে হবে। এটার মতো কিছু:
class MyClass{
private static $ref;
function MyClass(){
$ref = &$this;
}
public static function getReference(){
return self::$ref;
}
}
যতক্ষণ আপনি অবজেক্টটি জানেন (এবং আপনি পিএইচপি 5.2 বা উচ্চতর ব্যবহার করেন - বর্তমান স্থিতিশীল পিএইচপি সংস্করণ 5.5, 5.4 এখনও সমর্থিত, 5.3 জীবনের শেষ), আপনি কেবল remove_filter()
পদ্ধতিটি দিয়ে এটিকে সরাতে পারবেন । আপনাকে যা মনে রাখতে হবে তা হ'ল অবজেক্ট, পদ্ধতি-নাম এবং অগ্রাধিকার (যদি ব্যবহৃত হয়):
remove_filter('comment_array', [$this, 'FbComments']);
তবে আপনি আপনার কোডটিতে কিছুটা ভুল করেন। অ্যাম্পারস্যান্ডের $this
সাথে উপসর্গ ব্যবহার করবেন না &
, এটি পিএইচপি 4 (!) এ প্রয়োজন ছিল এবং এটি দীর্ঘ সময় ধরে ছাড়। এটি আপনার হুককে সমস্যাযুক্ত হিসাবে কাজ করতে পারে তাই কেবল এটিকে এড়িয়ে চলুন:
add_filter('comments_array', [$this, 'FbComments]));
এবং এটাই.
$this
বাইরে থেকে আপনার কোনও অ্যাক্সেস নেই (অন্য একটি প্লাগইন / থিম)।
&
আপনার থেকে&$this
এটি অপসারণ করা উচিত , এটি একটি পিএইচপি 4 জিনিস