add_action 클래스를 참조 ..

‘add_action’에서 함수 대신 클래스를 참조 할 수 있습니까? 알아낼 수 없습니다. 다음은 해당 기능의 기본 예입니다.

add_action( 'admin_init', 'MyClass' );
class MyClass {
     function __construct() {
          .. This is where stuff gets done ..
     }
}

그래서, 그것은 작동하지 않습니다. 나는 또한 시도했다 :

$var = new MyClass();
add_action( 'admin_init', array( &$var ) );

과:

$var = new MyClass();
add_action( 'admin_init', array( &$var, '__construct' ) );

그리고 또한:

add_action( 'admin_init', 'MyClass::__construct' );

어쨌든 클래스를로드하는 별도의 함수를 만들지 않고도이 작업을 수행 할 수 있습니까? add_action을 통해 클래스 생성자를 실행할 수 있기를 원합니다. 볼 롤링을하기 위해로드해야하는 전부입니다.



답변

아니요, 직접적으로가 아니라 후크를 통해 클래스를 ‘초기화’하거나 인스턴스화 할 수 없습니다. 몇 가지 추가 코드가 항상 필요합니다. 웜 캔을 직접 열 때이를 수행하는 것은 바람직하지 않습니다.

더 좋은 방법은 다음과 같습니다.

class MyClass {
     function __construct() {
          add_action( 'admin_init',array( $this, 'getStuffDone' ) );
     }
     function getStuffDone() {
          // .. This is where stuff gets done ..
     }
}
$var = new MyClass();

물론 일반적인 경우를 위해 인터페이스 클래스를 만들어 더 단순화 할 수 있습니다.

class IGetStuffDone {
    function IGetStuffDone(){
        add_action( 'admin_init',array( $this, 'getStuffDone' ) );
    }
    public abstract function getStuffDone();
}

인터페이스로서이 유형의 객체를 직접 만들 수는 없지만 하위 클래스를 만들면 다음과 같이 말할 수 있습니다.

class CDoingThings extends IGetStuffDone {
    function getStuffDone(){
        // doing things
    }
}
$var = new CDoingThings();

그러면 모든 후크가 자동으로 추가되므로 서브 클래스에서 정확히 수행되는 작업을 정의한 후 작성하면됩니다.

생성자

나는 생성자를 후크 함수로 추가하지 않을 것이고, 나쁜 습관이며, 많은 비정상적인 이벤트를 일으킬 수 있습니다. 또한 대부분의 언어에서 생성자는 인스턴스화되는 객체를 반환하므로 후크가 필터와 같은 것을 반환 해야하는 경우 원하는대로 필터링 된 변수를 반환하지 않지만 대신 클래스 객체를 반환합니다.

생성자 또는 소멸자를 호출하는 것은 어떤 언어를 사용하든 절대 수행 해서는 안되는 프로그래밍 습관 입니다.

또한 생성자는 실제 작업이 아닌 사용 준비를 초기화하기 위해 객체를 구성해야합니다. 객체에 의해 수행되는 작업은 별도의 기능이어야합니다.

정적 클래스 메서드이며 인스턴스화 / 초기화가 필요하지 않습니다

클래스 메소드가 정적 클래스 메소드 인 경우 $this아래 표시된 것처럼 클래스 이름을 따옴표로 묶을 수 있습니다.

class MyClass {
     public static function getStuffDone() {
          // .. This is where stuff gets done ..
     }
}
add_action( 'admin_init', array('MyClass','getStuffDone' ) );

클로저 및 PHP 5.3

슬프게도 새로운 클래스를 만드는 선을 피할 수는 없습니다. 이것을 건너 뛸 수있는 유일한 다른 해결책은 여전히 ​​해당 라인을 가진 보일러 플레이트 코드를 포함하며 PHP 5.3 이상이 필요합니다.

add_action('admin_init',function(){
    $var = new MyClass();
    $var->getStuffDone();
});

어느 시점에서 클래스를 건너 뛰고 함수를 사용할 수 있습니다.

add_action('admin_init',function(){
    // do stuff
});

그러나 이제 익명 함수의 스펙터를 소개했습니다. 를 사용하여 위의 작업을 제거 할 수있는 방법이 없으며 remove_action, 이는 다른 사람의 코드로 작업해야하는 개발자에게 큰 고통을 줄 수 있습니다.

앰퍼샌드

다음과 같이 사용 된 조치가 표시 될 수 있습니다.

array( &$this, 'getStuffDone' );

이것은 나쁘다 . &객체가 참조가 아닌 값으로 전달 될 때 PHP 4에서 다시 추가되었습니다. PHP 4는 10 년이 넘었으며 WordPress에서 오랫동안 지원하지 않았습니다.

후크와 필터를 추가 할 때 사용할 이유없으며&this 참조를 제거해도 아무런 문제가 없으며 향후 PHP 버전과의 호환성을 향상시킬 수 있습니다

대신 이것을 사용하십시오 :

array( $this, 'getStuffDone' );

답변

예제 클래스

노트:

  • 수업을 한 번만 시작하십시오
    • 우선 순위 0으로 전화하므로 나중에 기본 우선 순위로 동일한 후크를 사용할 수 있습니다.
    • ! class_exists두 번 전화하지 않도록 in에 싸서 init 호출자를 안에 넣으십시오.
  • init함수와 클래스를 var로 만드십시오.static
  • 클래스를 호출 할 때 init 내부에서 생성자를 호출하십시오 new self.

여기에 예가 있습니다

if ( ! class_exists( 'WPSESampleClass' ) )
{
    // Init the class on priority 0 to avoid adding priority inside the class as default = 10
    add_action( 'init', array ( 'WPSESampleClass', 'init' ), 0 );

class WPSESampleClass
{
    /**
     * The Class Object
     */
    static private $class = null;

    public static function init()
    {
        if ( null === self::$class )
            self :: $class = new self;

        return self :: $class;
    }

    public function __construct()
    {
        // do stuff like add action calls:
        add_action( 'init', array( $this, 'cb_fn_name' ) );
    }

    public function cb_fn_name()
    {
        // do stuff 
    }
} // END Class WPSESampleClass

} // endif;

PHP 5+

제발 나가 &십시오. 우리는 이미 php4를 넘어 섰습니다. 🙂


답변

if (!class_exists("AllInOneWoo")){
    class AllInOneWoo {
        function __construct(){
            add_action('admin_menu', array($this, 'all_in_one_woo') );
        }
        function all_in_one_woo(){
            $page_title = 'All In One Woo';
            $menu_title = 'All In One Woo';
            $capability = 'manage_options';
            $menu_slug  = 'all-in-one-woo-menu';
            $function   = array($this, 'all_in_one_woo_menu');
            $icon_url   = 'dashicons-media-code';
            $position   = 59;

            add_menu_page($page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position);
        }
        function all_in_one_woo_menu(){?>
            <div class="wrap">
                <h1><?php _e('All In One Woo', 'all_in_one_woo'); ?></h1>
            </div>
        <?php }
    }// end class
}// end if

if (class_exists("AllInOneWoo")){
    $all_in_one_woo = new AllInOneWoo();
}

답변

처음 에로드 할 필요없이 클래스에서 이벤트를 트리거 할 수 있습니다 . 전체 클래스를 미리로드하지 않고 WordPress 필터 및 작업에 액세스해야하는 경우에 유용합니다.

다음은 매우 간단한 예입니다

<?php
class MyClass
{
    public static function init()
    {
        add_filter( 'the_content', array('MyClass', 'myMethod') );
    }

    public static function myMethod($content)
    {
        $content = $content . 'Working without loading the object';
    }
}

MyClass::init();

이것은 카이저의 대답의 매우 단순화 된 버전이지만 간단한 용어로 행동을 보여줍니다. 이 스타일을 처음 보는 사람들에게 유용 할 수 있습니다.

필요한 경우 다른 방법으로도 객체를 시작할 수 있습니다. 개인적 으로이 방법을 사용하여 플러그인의 선택적 부분이 스크립트를 대기열에 넣을 수 있지만 AJAX 요청에서 객체를 트리거하는 것만 허용합니다.


답변

이것은 나를 위해 작동합니다 :

class foo
{
    public static function bar()
    {
        echo 'it works!';
    }
}

add_action('foo_bar', array('foo', 'bar'));

답변

일반적으로 전체 클래스 를 후크에 추가하지는 않습니다 . add_action()/의 add_filter()후크 콜백 기대 기능 , 에서 참조 할 클래스 내를 .

init()클래스 내에 함수가 있고 WordPress init후크 에 연결하려고 한다고 가정 해 봅시다 .

당신 넣어 add_action()전화를 안쪽 과 같이 콜백을 식별 한 후 클래스 및 :

add_action( 'init', array( $this, 'init' ) );

(참고 : 클래스의 네임 스페이스가 적절하다고 가정합니다. 그렇지 않으면 콜백 함수의 네임 스페이스를 사용해야합니다.)


답변

인스턴스화 된 객체 대신 클래스 이름을 전달하여이를 수행 할 수 있어야합니다.

add_action( 'init', array( 'MyClass', '__construct' ) );

(이론적으로 다른 솔루션도 작동해야합니다.

$var = new MyClass();
add_action( 'admin_init', array( $var, '__construct' ) );

왜 그렇지 않은지 확실하지 않습니다. 어쩌면 참조로 전화하지 않으면?)