Kesalahan PHP dengan penangan kode pendek dari suatu kelas

13

Saat ini saya menggunakan aliran umum berikut untuk menambahkan kode pendek untuk sebuah plugin.

class MyPlugin {

    private $myvar;

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

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

Sekarang ketika kelas ini dan metode itu disebut saya mendapatkan kesalahan berikut.

Kesalahan fatal: Menggunakan $ this saat tidak dalam konteks objek di ...

(Jalur no adalah tempat saya telah mencetak $this->myvar)

Apakah ini masalah di ujung Wordpress atau ada sesuatu yang saya lakukan salah? Tampaknya menjadi sesuatu yang sangat sederhana.

xmaestro
sumber
di luar topik - buat fungsinya static.
kaiser

Jawaban:

31

Seperti yang dikatakan kesalahan, Anda memerlukan instance kelas untuk digunakan $this. Setidaknya ada tiga kemungkinan:

Jadikan semuanya statis

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' ) );

Tapi itu bukan OOP nyata lagi, hanya namespace.

Buat objek nyata terlebih dahulu

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' ) );

Ini bekerja. Tetapi Anda mengalami beberapa masalah yang tidak jelas jika ada yang ingin mengganti kode pendek.

Jadi tambahkan metode untuk memberikan instance kelas:

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' ] );

Sekarang, ketika seseorang ingin mendapatkan objek contoh, ia hanya perlu menulis:

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

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

Solusi lama: buat objek di kelas Anda

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' ) );
fuxia
sumber
thanx man ... itu info berharga karena wordpress.org tidak memberi tahu sebanyak ini di halaman dokumentasi add_shortcode mereka. Saya telah menemukan solusinya tetapi karena Anda telah mengesampingkannya sebagai praktik yang buruk dan Anda memiliki solusi yang lebih baik maka saya menandai masalah ini sebagai diselesaikan :)
xmaestro
Saya benar-benar menyesal untuk menggali pertanyaan lama ini, tapi bisa Anda plase menjelaskan apa baris ini tidak: NULL === self::$instance and self::$instance = new self;? Saya agak bingung karena ===dan anddigunakan, tetapi tanpa if, jika Anda tahu apa yang saya maksud.
Sven
@Ven Ini adalah pemeriksaan untuk mencegah instance kedua. Itu membuat kelas ini Singleton ... Saya tidak akan melakukannya saat ini. Saya akan menulis ulang jawaban ini.
fuxia
Terima kasih untuk itu! Saya pikir sekarang saya berada di jalur yang benar, meskipun menakjubkan betapa rumitnya dapat menggunakan WordPress & OOP ;-)
Sven
2
@Ven WordPress inti dituliskan sebagai anti-OOP mungkin. Bahkan kode baru mengabaikan semua hal yang dipelajari dunia PHP selama sepuluh tahun terakhir, injeksi ketergantungan misalnya. Jadi ya, OOP di plugin dan tema WordPress selalu menjadi peretasan. : /
fuxia
7

Anda dapat menggunakan seperti ini, kode pendek di dalam Kelas

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();

Jika Anda ingin mengakses konten kode pendek dari kelas lain. Anda bisa melakukan ini.

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 );
Pavnish Yadav
sumber
1
Saya sangat suka solusi ini. Ini sangat bersih dan mudah dimengerti. Sisi pengembang React.js saya senang dengan ini.
AaronDancer
1

Pastikan Anda membuat instance kelas Anda sebelum menggunakannya kecuali Anda yakin itu seharusnya dipanggil secara statis. Ketika Anda memanggil metode secara statis, Anda tidak menggunakan instance apa pun dan karena itu tidak memiliki akses ke variabel atau metode anggota.

menyedihkan
sumber