클래스의 짧은 코드 처리기에서 PHP 오류


13

현재 플러그인의 단축 코드를 추가하기 위해 다음과 같은 일반적인 흐름을 사용하고 있습니다.

class MyPlugin {

    private $myvar;

    function baztag_func() {
        print $this->myvar;            
    }
}

add_shortcode( 'baztag', array('MyPlugin', 'baztag_func') );

이제이 클래스와 메서드가 호출되면 다음 오류가 발생합니다.

치명적 오류 : 개체 컨텍스트에 없을 때 $ this 사용 중 ...

(라인 번호는 내가 인쇄 한 곳입니다 $this->myvar)

이것이 Wordpress의 끝에 문제입니까, 아니면 내가 잘못하고있는 것이 있습니까? 정말 간단한 것 같습니다.


오프 주제 -기능을 static합니다.
카이저

답변:


31

오류에 따르면 사용할 클래스의 인스턴스가 필요합니다 $this. 최소한 세 가지 가능성이 있습니다.

모든 것을 정적으로 만드십시오

class My_Plugin
{
    private static $var = 'foo';

    static function foo()
    {
        return self::$var; // never echo or print in a shortcode!
    }
}
add_shortcode( 'baztag', array( 'My_Plugin', 'foo' ) );

그러나 그것은 더 이상 실제 OOP가 아니며 단지 이름을 지정하는 것입니다.

실제 객체를 먼저 생성

class My_Plugin
{
    private $var = 'foo';

    public function foo()
    {
        return $this->var; // never echo or print in a shortcode!
    }
}

$My_Plugin = new My_Plugin;

add_shortcode( 'baztag', array( $My_Plugin, 'foo' ) );

이것은 ... 작동합니다. 그러나 당신은 모호한 문제에 부딪칩니다. 누군가가 단축 코드를 교체하려면 합니다.

따라서 클래스 인스턴스를 제공하는 메소드를 추가하십시오.

final class My_Plugin
{
    private $var = 'foo';

    public function __construct()
    {
        add_filter( 'get_my_plugin_instance', [ $this, 'get_instance' ] );
    }

    public function get_instance()
    {
        return $this; // return the object
    }

    public function foo()
    {
        return $this->var; // never echo or print in a shortcode!
    }
}

add_shortcode( 'baztag', [ new My_Plugin, 'foo' ] );

이제 누군가가 객체 인스턴스를 얻으려고 할 때 다음과 같이 작성하면됩니다.

$shortcode_handler = apply_filters( 'get_my_plugin_instance', NULL );

if ( is_a( $shortcode_handler, 'My_Plugin ' ) )
{
    // do something with that instance.
}

오래된 해결책 : 클래스에서 객체 만들기

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_shortcode( 'baztag', array( My_Plugin::get_instance(), 'foo' ) );

고맙습니다 man ... wordpress.org가 add_shortcode 문서 페이지에서 이것을 많이 말하지 않았기 때문에 귀중한 정보입니다. 나는 해결책을 알아 냈지만 나쁜 습관으로 배제하고 더 나은 해결책을
찾았 으므로이

이 오래된 질문을 파헤쳐 서 정말 유감이지만,이 라인이하는 일을 자세히 설명해 줄 수 NULL === self::$instance and self::$instance = new self;있습니까? 내가 무슨 뜻인지 알면 나는 혼란스러워 ===하고 and사용되지만 if.
Sven

@Sven 두 번째 인스턴스를 방지하기위한 검사입니다. 그것은이 수업을 싱글 톤으로 만듭니다. 저는 요즘 그렇게하지 않을 것입니다. 이 답변을 다시 쓰겠습니다.
fuxia

고마워요! WordPress & OOP를 사용하는 것이 얼마나 복잡한 지 놀랍지 만 지금은 올바른 방향으로 가고 있다고 생각합니다.
Sven

2
@Sven WordPress 코어는 최대한 안티 -OOP로 작성되었습니다. 새로운 코드조차도 지난 10 년 동안 PHP 환경의 나머지 부분에서 배운 모든 것을 무시합니다 (예 : 의존성 주입). 예, WordPress 플러그인 및 테마의 OOP는 항상 해킹 적입니다. : /
fuxia

7

클래스 내부에서 이와 같이 짧은 코드를 사용할 수 있습니다.

class stockData{


    function __construct() {
        add_shortcode( 'your_shortcode_name', array( $this, 'showData' ) );
        //add_action('login_enqueue_scripts', array( $this,'my_admin_head'));
    }

    function showData(){
        return '<h1>My shortcode content</h1>' ;
    }
}

$object=new stockData();

다른 클래스의 단축 코드 컨텐츠에 액세스하려는 경우. 이렇게 할 수 있습니다.

class my_PluginClass {

  public function __construct( $Object ) {

    $test = add_shortcode( 'your_shortcode_name', array( $Object, 'your_method_name' ) );

  }

}

class CustomHandlerClass{

  public function your_method_name( $atts, $content ) {
     return '<h1>My shortcode content</h1>' ;
  }
}

$Customobject  = new CustomHandlerClass();
$Plugin         = new my_PluginClass( $Customobject );

1
나는이 솔루션을 정말 좋아한다. 정말 깨끗하고 이해할 수 있습니다. 내 React.js 개발자 측은 이것에 만족합니다.
AaronDancer

1

정적으로 호출되지 않는 한 클래스를 사용하기 전에 클래스의 인스턴스를 만들어야합니다. 메서드를 정적으로 호출하면 인스턴스를 사용하지 않으므로 멤버 변수 또는 메서드에 액세스 할 수 없습니다.

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