WP 플러그인에서 수업을 시작하는 가장 좋은 방법은?


89

나는 플러그인을 만들었고, 물론 나는 멋진 OO 접근 방식을 원했습니다. 이제 내가하고있는 일은이 클래스를 만든 다음 아래 에서이 클래스의 인스턴스를 만드는 것입니다.

class ClassName {

    public function __construct(){

    }
}

$class_instance = new ClassName();  

나는이 수업을 시작하는 더 WP 방법이 있다고 가정하고, 사람들 init()__construct()하나 보다 기능 을 선호한다고 말하는 사람들을 만났습니다 . 마찬가지로 다음과 같은 후크를 사용하여 소수의 사람들을 발견했습니다.

class ClassName {

    public function init(){

    }
}
add_action( 'load-plugins.php', array( 'ClassName', 'init' ) );

일반적으로로드시 WP 클래스 인스턴스를 작성하고이를 전 세계적으로 액세스 가능한 변수로 만드는 가장 좋은 방법은 무엇입니까?

참고 : 흥미로운 측면으로, register_activation_hook()에서 호출 할 수는 있지만 두 번째 예제를 사용하여 __construct호출 할 수는 없습니다 init(). 아마도이 시점에서 누군가 나를 깨우칠 수있을 것입니다.

편집 : 모든 답변에 감사드립니다. 클래스 자체에서 초기화를 처리하는 방법에 대해서는 상당히 논쟁의 여지가 있지만 add_action( 'plugins_loaded', ...);실제로 실제로 시작하는 가장 좋은 방법 인 꽤 좋은 합의가 있다고 생각 합니다 ...

편집 : 문제를 혼란스럽게하기 위해 이것을 사용하는 것도 보았습니다 (멋진 OO 클래스를 함수로 바꾸는 것이 그 요점을 잃는 것처럼 보이기 때문에이 방법을 직접 사용하지는 않습니다).

// Start up this plugin
add_action( 'init', 'ClassName' );
function ClassName() {
    global $class_name;
    $class_name = new ClassName();
}

1
마지막 편집과 관련하여 클래스와 동일한 플러그인 파일에 포함되어 있으면 다소 쓸모가 없습니다. 내가 설명한 방법에 따라 클래스를 인스턴스화 할 수도 있습니다. 별도의 파일에 있더라도 여전히 의미가 없습니다. 내가 볼 수있는 유일한 사례는 플러그인 파일 외부, 테마 등에서 클래스를 인스턴스화 할 수있는 래퍼 함수를 ​​만들려는 경우입니다. 그럼에도 불구하고 조건부와 후크를 올바르게 사용하면 인스턴스화를 세밀하게 제어하여 플러그인 사용에 집중할 수 있기 때문에 그 논리 뒤에 어떤 논리가 있는지 묻어 야합니다.
Adam

나는 이것에 동의하지만, 몇 가지 WP 플러그인에서 발견했을 때 가치가 있다고 생각했습니다.
kalpaitch

답변:


60

좋은 질문은 여러 가지 접근 방식이 있으며 달성하려는 대상에 따라 다릅니다.

나는 종종한다;

add_action( 'plugins_loaded', array( 'someClassy', 'init' ));

class someClassy {

    public static function init() {
        $class = __CLASS__;
        new $class;
    }

    public function __construct() {
           //construct what you see fit here...
    }

    //etc...
}

WPSE 회원 인 toscho 대화방에서이 주제에 대한 최근 토론의 결과로 나온보다 철저한 심층 사례를 볼 수 있습니다 .

빈 생성자 방식

다음은 빈 생성자 접근 방식을 완전히 보여주는 위의 요지에서 얻은 장점 / 단점의 발췌입니다.

  • 장점 :

    • 단위 테스트는 후크를 자동으로 활성화하지 않고 새 인스턴스를 작성할 수 있습니다. 싱글 톤 없음.

    • 전역 변수가 필요하지 않습니다.

    • 플러그인 인스턴스 작업을 원하는 사람은 T5_Plugin_Class_Demo :: get_instance ()를 호출하면됩니다.

    • 비활성화하기 쉽습니다.

    • 여전히 실제 OOP : 정적 인 작업 방법이 없습니다.

  • 불리:

    • 읽기 어려울까요?

내 의견의 단점은 약한 점이기 때문에 내가 선호하는 접근법은 아니지만 내가 선호하는 접근법이어야합니다. 실제로이 주제에 관해 언급해야 할 몇 가지 다른 무거운 가중치가 의심의 여지없이이 주제에 관한 주제를 취하게되는데,이 주제를 둘러싼 좋은 의견이 있기 때문입니다.


참고 : toscho 에서 3 또는 4 가지 비교를 통해 플러그인의 클래스를 인스턴스화하는 방법에 대한 장단점 을 찾아야합니다. 각 링크의 장점과 단점은 위의 링크가 선호하는 방법이었습니다. 다른 예제는이 주제와 좋은 대비를 제공합니다. 바라건대 toscho는 여전히 파일을 가지고 있습니다.

참고 : WPSE 응답 관련 예제와 비교이 주제를. 또한 WordPress의 클래스와 같은 최상의 솔루션입니다.

add_shortcode( 'baztag', array( My_Plugin::get_instance(), 'foo' ) );
class My_Plugin {

    private $var = 'foo';

    protected static $instance = NULL;

    public static function get_instance() {

        // create an object
        NULL === self::$instance and self::$instance = new self;

        return self::$instance; // return the object
    }

    public function foo() {

        return $this->var; // never echo or print in a shortcode!
    }
}

add_action ( 'plugins_loaded', ...)의 차이점은 무엇입니까? 그리고 add_action ( 'load-plugins.php', ...); 내가 사용한 예는 후자를 사용했다
kalpaitch

1
내가 이해하는 것에서 load-plugins.php는 작동하지만 핵심 update.php파일과 관련 이 있으며 초기화 중에 발생하는 일련의 이벤트와 그 이유 때문에 선호하는 기본 작업의 일부가 아닙니다. 이 경우 적용되는 후크를 사용하십시오 plugins_loaded. 이것이 내가 액션 레퍼런스 때 일어나는 일에 대한 빠른 스냅 샷이라고 종종 언급하는 것 입니다. 내 설명이 완전하지 않습니다.
Adam

4
나는이 싱글 톤 같은 접근법을 좋아한다. 그러나 초기화 액션 후크로 plugins_loaded를 사용하여 질문합니다. 이 후크는 모든 플러그인이로드 된 후에 실행 됩니다. 그 후 훅을 연결하면 그 훅을 도용 할 수 있으며 plugins_loaded에 연결된 다른 플러그인 또는 테마와의 충돌 또는 시작 순서 문제에 재미를 느낄 수 있습니다. 초기화 방법을 실행하기 위해 어떤 작업에도 의존하지 않습니다. 플러그인 아키텍처는 작업이 아닌 인라인으로 실행되도록 설계되었습니다.
Tom Auger

2
사용하는 경우 작업이 트리거 register_activation_hook()되기 전에 해당 기능을 호출해야합니다 plugins_loaded.
Geert

1
추가 정보는 @mikeschinkel의이 게시물과 의견의 dicuss를 참조하십시오. hardcorewp.com/2012/…
bueltge

78

원래 질문이 나온지 정확히 2 년 후에 여기에 도착 하면 몇 가지 지적해야 할 것이 있습니다. (내가 많은 것을 지적하도록 요구하지 마십시오 ).

적절한 후크

플러그인 클래스를 인스턴스화하려면 적절한 후크를 사용해야합니다. 클래스가하는 일에 따라 다르기 때문에 일반적인 규칙은 없습니다.

"plugins_loaded"관리자, 프론트 엔드 및 AJAX 요청에 대해 이와 같은 후크가 발생하기 때문에 매우 초기 후크를 사용하는 것이 종종 의미가 없지만, 종종 필요할 때만 플러그인 클래스를 인스턴스화 할 수 있기 때문에 나중에 후크가 훨씬 낫습니다.

예를 들어 템플릿을위한 작업을 수행하는 클래스를 인스턴스화 할 수 있습니다 "template_redirect".

일반적으로 말하기 전에 클래스를 인스턴스화 해야하는 경우는 거의 없습니다 "wp_loaded".

신 클래스 없음

이전 답변에서 예제로 사용 된 모든 클래스의 대부분은 "Prefix_Example_Plugin"또는 "My_Plugin"... 과 같은 클래스를 사용합니다. 아마도 플러그인 의 기본 클래스 가 있음을 나타냅니다 .

글쎄, 하나의 단일 클래스로 플러그인을 만들지 않는 한 (이 경우 플러그인 이름 다음에 이름을 지정하는 것이 절대적으로 합리적 임) 전체 플러그인을 관리하는 클래스를 작성하십시오 (예 : 플러그인에 필요한 모든 후크 추가 또는 다른 모든 플러그인 클래스 인스턴스화) )는 신의 대상 의 예로 나쁜 습관으로 간주 될 수 있습니다 .

객체 지향 프로그래밍 코드 에서 "S"가 "단일 책임 원칙" 을 나타내는 경우 SOLID 인 경향이 있습니다 .

그것은 모든 수업이 하나의 일을해야한다는 것을 의미합니다. WordPress 플러그인 개발에서 개발자는 단일 플러그인 을 사용하여 기본 플러그인 클래스를 인스턴스화하지 말아야하지만 클래스 책임에 따라 다른 후크를 사용하여 다른 클래스를 인스턴스화해야합니다.

생성자에서 후크 방지

이 주장은 다른 답변에서 소개되었지만이 개념을 언급하고 단위 테스트의 범위에서 꽤 광범위하게 설명 된 이 다른 답변을 연결하고 싶습니다 .

거의 2015 : PHP 5.2는 좀비를위한 것입니다

2014 년 8 월 14 일부터 PHP 5.3의 수명이 다했습니다 . 확실히 죽었다. PHP 5.4는 2015 년 내내 지원 될 예정입니다. 제가 작성하는 순간에 다른 해를 의미합니다.

그러나 WordPress는 여전히 PHP 5.2를 지원하지만, 특히 코드가 OOP 인 경우 해당 버전을 지원하는 단일 코드 행을 작성해서는 안됩니다.

여러 가지 이유가 있습니다.

  • PHP 5.2는 오래 전에 죽었고 보안 픽스가 발표되지 않았습니다.
  • PHP 5.3은 PHP로 기능이 많이 추가 익명 함수네임 스페이스 동네 짱 ALLES
  • 최신 버전의 PHP는 훨씬 빠릅니다 . PHP는 무료입니다. 업데이트는 무료입니다. 더 빠르고 안전한 버전을 무료로 사용할 수 있다면 왜 느리고 안전하지 않은 버전을 사용해야합니까?

PHP 5.4+ 코드를 사용하지 않으려면 5.3+ 이상을 사용하십시오

이 시점에서 내가 여기까지 말한 내용을 기반으로 이전 답변을 검토 할 때입니다.

더 이상 5.2를 신경 쓰지 않아도되면 네임 스페이스를 사용할 수 있고 사용해야합니다.

더 나은 설명 단일 책임 원칙을 위해, 내 예는 3 개 클래스, 않습니다 하나를 사용합니다 뭔가를 프론트 엔드에서 백엔드에 하나 두 경우 모두에 사용되는 세 번째.

관리 클래스 :

namespace GM\WPSE\Example;

class AdminStuff {

   private $tools;

   function __construct( ToolsInterface $tools ) {
     $this->tools = $tools;
   }

   function setup() {
      // setup class, maybe add hooks
   }

}

프론트 엔드 클래스 :

namespace GM\WPSE\Example;

class FrontStuff {

   private $tools;

   function __construct( ToolsInterface $tools ) {
     $this->tools = $tools;
   }

   function setup() {
      // setup class, maybe add hooks
   }

}

도구 인터페이스 :

namespace GM\WPSE\Example;

interface ToolsInterface {

   function doSomething();

}

그리고 다른 두 가지에서 사용되는 Tools 클래스 :

namespace GM\WPSE\Example;

class Tools implements ToolsInterface {

   function doSomething() {
      return 'done';
   }

}

이 클래스가 있으면 적절한 후크를 사용하여 인스턴스화 할 수 있습니다. 다음과 같은 것 :

require_once plugin_dir_path( __FILE__ ) . 'src/ToolsInterface.php';
require_once plugin_dir_path( __FILE__ ) . 'src/Tools.php';

add_action( 'admin_init', function() {

   require_once plugin_dir_path( __FILE__ ) . 'src/AdminStuff.php';
   $tools = new GM\WPSE\Example\Tools;
   global $admin_stuff; // this is not ideal, reason is explained below
   $admin_stuff = new GM\WPSE\Example\AdminStuff( $tools ); 
} );

add_action( 'template_redirect', function() {

   require_once plugin_dir_path( __FILE__ ) . 'src/FrontStuff.php';
   $tools = new GM\WPSE\Example\Tools;
   global $front_stuff; // this is not ideal, reason is explained below
   $front_stuff = new GM\WPSE\Example\FrontStuff( $tools );    
} );

의존성 역전 및 의존성 주입

위의 예제에서 네임 스페이스와 익명 함수를 사용하여 서로 다른 후크에서 다른 클래스를 인스턴스화하여 위에서 말한 것을 실제로 적용했습니다.

네임 스페이스가 접두사없이 이름이 지정된 클래스를 작성하는 방법을 참고하십시오.

위에서 간접적으로 언급 한 또 다른 개념 인 Dependency Injection 을 적용했습니다.이 방법 은 SOLID 약어의 "D"인 Dependency Inversion Principle 을 적용하는 한 가지 방법 입니다.

Tools들이 인스턴스화 될 때 클래스는이 방법으로는 책임을 분리하는 것이 가능하므로, 다른 두 클래스에 "주입"입니다.

또한, AdminStuffFrontStuff클래스가 사용하는 타입 힌트를 그들이 구현하는 클래스를 필요로 선언 ToolsInterface.

이런 식으로 우리 자신이나 코드를 사용하는 사용자는 동일한 인터페이스의 서로 다른 구현을 사용하여 코드를 구체적인 클래스에 연결하지 않고 추상화에 만들 수 있습니다. 바로 Dependency Inversion Principle의 개념입니다.

그러나, 상기 예는 추가로 개선 될 수있다. 방법을 보자.

오토로더

더 읽기 쉬운 OOP 코드를 작성하는 좋은 방법은 유형 (인터페이스, 클래스) 정의를 다른 코드와 혼합 하지 않고 모든 유형을 자체 파일에 넣는 것입니다.

이 규칙은 또한 PSR-1 코딩 표준 1 중 하나입니다 .

그러나 이렇게하려면 클래스를 사용하기 전에 클래스가 포함 된 파일이 필요합니다.

이것은 압도적이지만 PHP는 이름에 따라 파일을로드하는 콜백을 사용하여 필요할 때 클래스를 자동로드하는 유틸리티 기능 을 제공 합니다 .

네임 스페이스를 사용하면 폴더 구조를 네임 스페이스 구조와 일치시킬 수 있으므로 매우 쉽습니다.

그것은 가능할뿐만 아니라 다른 PSR 표준이기도합니다 (또는 더 나은 2 : PSR-0 은 더 이상 사용되지 않으며 PSR-4 ).

이러한 표준에 따라 사용자 정의 오토로더를 코딩하지 않고도 오토로드를 처리하는 다양한 도구를 사용할 수 있습니다.

나는 그 말을 워드 프레스 코딩 표준이 파일을 명명 다른 규칙이있다.

따라서 WordPress 코어 용 코드를 작성할 때 개발자는 WP 규칙을 따라야하지만 사용자 정의 코드를 작성할 때는 개발자가 선택하지만 PSR 표준을 사용하는 것이 이미 작성된 도구를 사용하는 것이 더 쉽습니다 2 .

글로벌 액세스, 레지스트리 및 서비스 로케이터 패턴.

WordPress에서 플러그인 클래스를 인스턴스화 할 때 가장 큰 문제 중 하나는 코드의 다양한 부분에서 액세스하는 방법입니다.

WordPress 자체는 전역 접근 방식을 사용합니다 . 변수는 전역 범위에 저장되어 어디에서나 액세스 할 수 있습니다. 모든 WP 개발자 global는 경력에 수천 번 단어를 입력 합니다.

이것은 또한 위의 예에서 사용한 접근 방식이지만 악한 것 입니다.

이 답변은 이미 너무 길어서 이유를 더 설명 할 수는 없지만 "전역 변수 악" 에 대한 SERP의 첫 번째 결과를 읽는 것이 좋은 출발점입니다.

그러나 어떻게 전역 변수를 피할 수 있습니까?

다른 방법이 있습니다.

여기에있는 오래된 답변 중 일부는 정적 인스턴스 접근 방식을 사용합니다 .

public static function instance() {

  if ( is_null( self::$instance ) ) {
    self::$instance = new self;
  }

  return self::$instance;
}

쉽고 간단하지만 액세스하려는 모든 클래스에 대해 패턴을 구현해야합니다.

또한 개발자 가이 메서드를 사용하여 기본 클래스에 액세스 한 다음이 클래스를 사용하여 다른 모든 클래스에 액세스하기 때문에이 방법으로 인해 신 클래스 문제가 발생하는 경우가 많습니다 .

나는 신 클래스가 얼마나 나쁜지 이미 설명 했으므로 플러그인이 하나 또는 두 개의 클래스에 액세스 할 수 있어야 할 때 정적 인스턴스 접근 방식이 좋은 방법입니다.

이것은 단지 몇 개의 클래스를 가진 플러그인에만 사용할 수 있다는 것을 의미하지는 않습니다. 실제로 의존성 주입 원리가 올바르게 사용되면 전역 적으로 액세스 할 수있는 많은 수의 복잡한 응용 프로그램을 만들 수 있습니다 개체의.

그러나 때때로 플러그인은 일부 클래스에 액세스 할 수 있어야 하며,이 경우 정적 인스턴스 접근 방식이 압도적입니다.

또 다른 가능한 방법은 레지스트리 패턴 을 사용하는 것 입니다 .

이것은 매우 간단한 구현입니다.

namespace GM\WPSE\Example;

class Registry {

   private $storage = array();

   function add( $id, $class ) {
     $this->storage[$id] = $class;
   }

   function get( $id ) {
      return array_key_exists( $id, $this->storage ) ? $this->storage[$id] : NULL;
   }

}

이 클래스를 사용하면 ID로 레지스트리 객체에 객체를 저장할 수 있으므로 레지스트리에 액세스하면 모든 객체에 액세스 할 수 있습니다. 물론 처음으로 개체를 만들 때 레지스트리에 추가해야합니다.

예:

global $registry;

if ( is_null( $registry->get( 'tools' ) ) ) {
  $tools = new GM\WPSE\Example\Tools;
  $registry->add( 'tools', $tools );
}

if ( is_null( $registry->get( 'front' ) ) ) {
  $front_stuff = new GM\WPSE\Example\FrontStuff( $registry->get( 'tools' ) );    
  $registry->add( 'front', front_stuff );
}

add_action( 'wp', array( $registry->get( 'front' ), 'wp' ) );

위의 예는 레지스트리를 유용하게 사용하려면 전역 적으로 액세스 할 수 있어야합니다. 단독 레지스트리의 글로벌 변수는 그리 나쁘지 는 않지만 , 글로벌이 아닌 순수 주의자에게는 레지스트리에 대한 정적 인스턴스 접근 방식 또는 정적 변수가있는 함수를 구현할 수 있습니다.

function gm_wpse_example_registry() {
  static $registry = NULL;
  if ( is_null( $registry ) ) {
    $registry = new GM\WPSE\Example\Registry;
  }
  return $registry;
}

함수가 처음 호출되면 레지스트리를 인스턴스화하고 후속 호출에서는 반환합니다.

클래스를 전역 적으로 액세스 할 수있게하는 또 다른 WordPress 관련 방법은 필터에서 개체 인스턴스를 반환하는 것입니다. 이 같은:

$registry = new GM\WPSE\Example\Registry;

add_filter( 'gm_wpse_example_registry', function() use( $registry ) {
  return $registry;
} );

그 후 모든 곳에서 레지스트리가 필요합니다.

$registry = apply_filters( 'gm_wpse_example_registry', NULL );

사용될 수있는 다른 패턴은 서비스 로케이터 패턴 입니다. 레지스트리 패턴과 비슷하지만 의존성 삽입을 사용하여 서비스 로케이터가 다양한 클래스로 전달됩니다.

이 패턴의 주요 문제점은 클래스 종속성을 숨겨 코드를 유지 관리하고 읽기가 더 어렵다는 것입니다.

DI 컨테이너

레지스트리 또는 서비스 로케이터를 전역 적으로 액세스 할 수 있도록하는 방법에 관계없이 객체를 저장해야하며 저장하기 전에 인스턴스화해야합니다.

클래스가 많고 의존성이 많은 복잡한 응용 프로그램에서 클래스를 인스턴스화하려면 많은 코드가 필요하므로 버그 가능성이 높아집니다. 존재하지 않는 코드에는 버그가 없습니다.

지난 몇 년 동안 PHP 개발자가 객체의 인스턴스를 쉽게 인스턴스화하고 저장 하여 의존성을 자동으로 해결 하는 데 도움이되는 일부 PHP 라이브러리가 나타났습니다 .

이 라이브러리는 종속성을 해결하는 클래스를 인스턴스화하고 필요한 경우 객체를 저장하고 반환하여 레지스트리 객체와 유사하게 작동 할 수 있기 때문에 종속성 주입 컨테이너라고합니다.

일반적으로 DI 컨테이너를 사용할 때 개발자는 응용 프로그램의 모든 클래스에 대한 종속성을 설정 한 다음 코드에서 클래스가 처음 필요할 때 적절한 종속성으로 인스턴스화되고 후속 요청에서 동일한 인스턴스가 반복해서 반환됩니다. .

일부 DI 컨테이너는 구성하지 않고 PHP 리플렉션을 사용하여 종속성을 자동으로 검색 할 수도 있습니다 .

잘 알려진 DI 컨테이너는 다음과 같습니다.

그리고 많은 다른 사람들.

간단한 플러그인의 경우 클래스와 클래스가 거의 필요하지 않은 종속성이 많지 않으므로 DI 컨테이너를 사용할 가치가 없습니다. 정적 인스턴스 메소드 또는 전역 액세스 가능한 레지스트리는 좋은 솔루션이지만 복잡한 플러그인에는 적합하지 않습니다. DI 컨테이너의 이점이 분명해집니다.

물론, DI 컨테이너 객체조차도 응용 프로그램에서 사용하기 위해 액세스 할 수 있어야하며,이를 위해 위에서 본 방법, 전역 변수, 정적 인스턴스 변수, 필터를 통한 객체 반환 등 중 하나를 사용할 수 있습니다.

작곡가

DI 컨테이너를 사용한다는 것은 종종 타사 코드를 사용하는 것을 의미합니다. 요즘, PHP, 우리가 필요로 할 때 외부 LIB (그래서뿐만 아니라 DI 컨테이너 만 사용하는 어떤 간단하게 다운로드하는 것이 좋습니다 간주되지 않습니다 우리의 응용 프로그램 폴더에 넣어 응용 프로그램의 일부가 아닌 코드). 우리가 다른 코드의 저자라도 마찬가지입니다.

외부 종속성에서 응용 프로그램 코드를 분리하는 것은 코드의 구성, 안정성 및 안정성이 향상 되었음을 나타 냅니다.

Composer 는 PHP 커뮤니티를 관리하기위한 사실상의 표준입니다. 멀리로 주류 뿐만 아니라 WP 커뮤니티, 그것을 사용하지 않을 경우 모든 PHP와 워드 프레스 개발자가 최소한 알아야 할 도구입니다.

이 답변은 이미 추가 토론을 할 수 있도록 책 크기가 조정되었으며, 여기에서 작곡가를 논의하는 것은 주제와 다를 수 있습니다.

자세한 내용은 작곡가 사이트를 방문하고 또한 이것에 읽기주는 가치 minisite를 큐레이터 @Rarst을 .


1 PSR은 PHP Framework Interop Group 에서 발표 한 PHP 표준 규칙입니다.

2 Composer (이 답변에서 언급 할 라이브러리)에는 오토로더 유틸리티도 포함되어 있습니다.


1
PHP 5.3도 수명이 다했다는 점도 주목해야한다. 책임있는 호스트는 기본값이 아닌 경우 옵션으로 최소 5.4를 제공합니다.
Tom J Nowell

2
"2014 년 8 월 14 일부터 PHP 5.3의 수명이 다했습니다. 확실히 죽었습니다." 아래의 첫 번째 라인이다 "PHP 5.2은 좀비입니다" @TomJNowell
gmazzap

3
궁금한 점이 있는데, "많은 것들"을 어떻게 지적 하십니까? ;-)
MikeSchinkel

전역 변수를 피하기 위해 함수 및 정적 변수가있는 레지스트리 패턴 아이디어가 마음에 듭니다. 함수가 처음 호출되면 레지스트리를 인스턴스화하고 후속 호출에서는 반환합니다.
Michael Ecklund

10

다음 구조를 사용합니다.

Prefix_Example_Plugin::on_load();

/**
 * Example of initial class-based plugin load.
 */
class Prefix_Example_Plugin {

    /**
     * Hooks init (nothing else) and calls things that need to run right away.
     */
    static function on_load() {

        // if needed kill switch goes here (if disable constant defined then return)

        add_action( 'init', array( __CLASS__, 'init' ) );
    }

    /**
     * Further hooks setup, loading files, etc.
     *
     * Note that for hooked methods name equals hook (when possible).
     */
    static function init(  ) {


    }
}

노트:

  • 바로 실행할 필요가있는 장소를 정의했습니다.
  • 조정에 대한 비활성화 / 재정의가 쉽습니다 (하나의 init방법을 분리)
  • 플러그인 클래스의 객체를 사용 / 필요하다고 생각하지 않습니다. 추적해야합니다. 이것은 OOP가 아닌 목적에 따라 가짜 이름 공간입니다 (대부분의 경우)

면책 조항 아직 단위 테스트를 사용하지 않고 ( myplate에 너무 많은 것들이 있음 ) 정적이 바람직하지 않을 수 있다고 들었습니다. 단위 테스트가 필요한 경우 이에 대해 조사하십시오.


3
단위 테스트에 관심이 많은 사람들은 정적 / 싱글 톤 솔루션을 좋아하지 않는다는 것을 알고 있습니다. 나는 당신이 정적을 사용하여 달성하려는 것을 완전히 이해하고 그렇게하는 데 따른 결과를 적어도 알고 있다면 그러한 방법을 구현하는 것이 완벽하다고 생각합니다. Stack Overflow
Adam

이것은 정말로 생각하게 만들었습니다. 그렇다면 왜 클래스를 사용하고 단순한 접두사 함수로 돌아 가지 않습니까? 더 깔끔한 기능 / 메소드 이름을 갖기 위해 이것을합니까? 나는 그것들이 "정적"b4로 중첩되어 있다는 것을 의미한다. 적절한 접두사를 사용하거나 무언가를 놓친 경우 이름 충돌 가능성은 단일 클래스 이름과 거의 같습니다.
제임스 미치

1
@JamesMitch 예, 모든 정적 메소드는 대부분 WP에서 사용되는 가짜 네임 스페이스를 가진 함수입니다. 그러나 클래스는이 경우에도 자동로드 및 상속과 같은 순수한 함수에 비해 몇 가지 장점이 있습니다. 최근에는 정적 메소드에서 의존성 주입 컨테이너로 구성된 실제 인스턴스화 된 객체로 이동했습니다.
Rarst

3

그것은 모두 기능에 달려 있습니다.

생성자가 호출되었을 때 스크립트를 등록하는 플러그인을 한 번 만들었으므로 후크에 연결해야했습니다 wp_enqueue_scripts.

functions.php파일이로드 될 때 호출하려는 경우 $class_instance = new ClassName();언급 한대로 인스턴스를 직접 만들 수도 있습니다 .

속도와 메모리 사용량을 고려할 수 있습니다. 나는 아무것도 모르지만 어떤 경우에는 호출되지 않은 후크가 있다고 상상할 수 있습니다. 해당 후크에서 인스턴스를 작성하면 일부 서버 자원을 절약 할 수 있습니다.


감사합니다. 위의 질문에도 두 가지 점이 있다고 가정합니다. 다른 하나는 __construct가 적합한 지 또는 init ()가 클래스를 초기화하는 더 좋은 방법인지 여부입니다.
kalpaitch

1
글쎄, 정적 init()메소드를 사용하여 클래스 인스턴스가 기존 변수를 덮어 쓸 수있는 다른 범위 대신 클래스 범위에서 호출됩니다.
Tim S.

0

나는 이것이 두 살이라는 것을 알고 있지만 PHP 5.3은 익명 메소드를 지원 하므로 다음과 같이 생각해 냈습니다.

add_action( 'plugins_loaded', function() { new My_Plugin(); } );

어떻게 든 가장 좋아합니다. 정규 생성자를 사용할 수 있으며 OOP 구조를 망쳐 놓는 "init"또는 "on_load"메소드를 정의 할 필요가 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.