ข้อผิดพลาด PHP พร้อมตัวจัดการรหัสย่อจากคลาส


13

ขณะนี้ฉันกำลังใช้โฟลว์ทั่วไปต่อไปนี้สำหรับการเพิ่มรหัสย่อสำหรับปลั๊กอิน

class MyPlugin {

    private $myvar;

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

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

ตอนนี้เมื่อชั้นนี้และมันเป็นวิธีการที่เรียกว่าฉันได้รับข้อผิดพลาดดังต่อไปนี้

ข้อผิดพลาดร้ายแรง: ใช้ $ นี่เมื่อไม่ได้อยู่ในบริบทวัตถุใน ...

(หมายเลขบรรทัดคือที่ฉันพิมพ์$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' ) );

thanx man ... นั่นคือข้อมูลที่มีค่าตั้งแต่ wordpress.org ไม่ได้บอกอะไรมากมายในหน้าเอกสาร add_shortcode ฉันได้คิดวิธีแก้ปัญหา แต่เนื่องจากคุณได้วินิจฉัยว่าเป็นวิธีปฏิบัติที่ไม่ดีและคุณมีวิธีแก้ปัญหาที่ดีกว่าดังนั้นฉันจึงทำเครื่องหมายปัญหานี้ว่าแก้ปัญหาแล้ว :)
xmaestro

ฉันเสียใจที่ต้องขุดคำถามเก่านี้ขึ้นมา แต่คุณช่วยอธิบายรายละเอียดได้ไหมว่าบรรทัดนี้ทำNULL === self::$instance and self::$instance = new self;อะไร? ฉันกำลังสับสนเล็กน้อยเพราะ===และandถูกนำมาใช้ แต่ไม่ifถ้าคุณรู้ว่าผมหมายถึง
Sven

@Sven นี่เป็นการตรวจสอบเพื่อป้องกันอินสแตนซ์ที่สอง มันทำให้คลาสนี้เป็นซิงเกิลตัน…ตอนนี้ฉันจะไม่ทำแบบนั้น ฉันจะเขียนคำตอบนี้ใหม่
fuxia

ขอบคุณสำหรับสิ่งนั้น! ฉันคิดว่าตอนนี้ฉันอยู่ในเส้นทางที่ถูกต้องแม้ว่ามันจะเป็นเรื่องน่าประหลาดใจที่ความซับซ้อนในการใช้ WordPress & OOP ;-)
Sven

2
@Sven WordPress core นั้นเขียนว่า anti-OOP มากที่สุด แม้แต่รหัสใหม่ก็ไม่สนใจสิ่งต่าง ๆ ที่เหลือในโลก PHP ได้เรียนรู้ในช่วงสิบปีที่ผ่านมาเช่นการพึ่งพาการฉีด ดังนั้นใช่ OOP ในปลั๊กอิน WordPress และธีมมักจะแฮก : /
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.