내 functions.php
파일에서 아래 필터를 제거하고 싶지만 클래스에 있기 때문에 어떻게 해야할지 모르겠습니다. 어떻게 remove_filter()
생겼을까 요?
add_filter('comments_array',array( &$this, 'FbComments' ));
88 번 라인에 있습니다 .
답변
아주 좋은 질문입니다. 그것은 플러그인 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가 전화를 걸고 _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에 의해 호출되었을 때만이 아닙니다.
답변
확실하지 않지만 싱글 톤을 사용해 볼 수 있습니다.
객체 참조를 클래스의 정적 속성에 저장 한 다음 정적 메서드에서 해당 정적 변수를 반환해야합니다. 이 같은:
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']);
그러나 코드에서 약간의 실수가 있습니다. PHP 4 (!)에서 필요했던 $this
앰퍼샌드 접두어를 사용 하지 마십시오 &
. 이렇게하면 후크를 처리하는 데 문제가 생길 수 있으므로 방해하지 마십시오.
add_filter('comments_array', [$this, 'FbComments]));
그리고 그게 다야.