ในfunctions.php
ไฟล์ของฉันฉันต้องการลบตัวกรองด้านล่าง แต่ฉันไม่แน่ใจว่าจะทำอย่างไรเนื่องจากอยู่ในชั้นเรียน สิ่งที่ควรremove_filter()
มีลักษณะอย่างไร
add_filter('comments_array',array( &$this, 'FbComments' ));
ในfunctions.php
ไฟล์ของฉันฉันต้องการลบตัวกรองด้านล่าง แต่ฉันไม่แน่ใจว่าจะทำอย่างไรเนื่องจากอยู่ในชั้นเรียน สิ่งที่ควรremove_filter()
มีลักษณะอย่างไร
add_filter('comments_array',array( &$this, 'FbComments' ));
คำตอบ:
นั่นเป็นคำถามที่ดีมาก มันลงไปที่หัวใจอันมืดมิดของปลั๊กอิน API และวิธีปฏิบัติในการเขียนโปรแกรมที่ดีที่สุด
สำหรับคำตอบต่อไปนี้ฉันสร้างปลั๊กอินง่าย ๆ เพื่อแสดงปัญหาพร้อมรหัสที่อ่านง่าย
<?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;
}
ตอนนี้เราเห็นสิ่งนี้:
WordPress ต้องการชื่อสำหรับตัวกรอง เราไม่ได้ให้บริการหนึ่งดังนั้นจึงเรียก WordPress _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'
สร้างวัตถุของคุณในการดำเนินการคาดเดาได้เช่นบน ไม่เพียงแค่เมื่อปลั๊กอินของคุณถูกเรียกโดย WordPressplugins_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 (!) และเกินกำหนดเป็นเวลานาน วิธีนี้จะทำให้การจัดการกับ hooks มีปัญหาของคุณดังนั้นเพียงแค่ปล่อยให้มันออกไป:
add_filter('comments_array', [$this, 'FbComments]));
และนั่นคือมัน
$this
จากภายนอก (ปลั๊กอิน / ชุดรูปแบบอื่น)
&
จากของคุณ&$this
มันเป็นสิ่ง PHP 4