Paket PHP Makro menawarkan injeksi ketergantungan penyetel berbasis penutupan (fungsi anonim) dengan menyediakan sifat yang dapat dimasukkan ke dalam kelas mana pun.
composer req aimeos/macro
Paket ini ditujukan untuk pengembang aplikasi, kerangka kerja, dan pustaka yang ingin mengizinkan penyesuaian perilaku kode oleh penggunanya.
Dalam aplikasi, kerangka kerja, atau pustaka yang dibuat untuk penyesuaian, penting untuk mengizinkan penimpaan fungsi yang ada agar dapat menyesuaikan perilakunya. Di sinilah makro sangat berguna karena makro dapat menambahkan kode khusus menggunakan penutupan.
Dengan paket PHP Macro, Anda juga dapat mengizinkan pengguna untuk menimpa metode di kelas dasar tanpa memaksa pengguna Anda untuk memperluas kelas ini. Paket PHP Makro TIDAK menggunakan refleksi atau peretasan lainnya, hanya metode PHP murni .
Ada beberapa pro dan kontra jika dibandingkan dengan injeksi ketergantungan berbasis kelas:
Pro:
Menipu:
Oleh karena itu, ini bukan pengganti injeksi ketergantungan berbasis kelas tetapi tambahan ringan untuk titik ekstensi kecil di mana injeksi ketergantungan penuh menggunakan antarmuka yang mengimplementasikan kelas terlalu merepotkan.
Hasil dari metode yang ada dapat dimodifikasi jika metode asli memeriksa makro yang ada dan menggunakannya sebagai implementasinya sendiri:
// original code
class Order
{
use Aimeos Macro Macroable;
private $ id = ' 123 ' ;
public function getOrderNumber ()
{
$ fcn = static :: macro ( ' orderNumber ' );
return $ fcn ? $ fcn ( $ this -> id ) : $ this -> id ;
}
};
Sekarang, Anda dapat menambahkan makro orderNumber
khusus yang akan digunakan sebagai gantinya:
// user code
Order:: macro ( ' orderNumber ' , function ( string $ id ) {
return date ( ' Y ' ) . ' - ' . $ id ;
} );
( new Order )-> getOrderNumber (); // now returns '2020-123'
Dengan demikian, Anda dapat menghasilkan keluaran sendiri atau meneruskan hasil yang berbeda ke metode berikutnya dalam aplikasi.
Saat makro dipanggil dalam konteks objek, makro juga bisa mengakses properti kelas:
// original code
class A
{
use Aimeos Macro Macroable;
private $ name = ' A ' ;
};
Di sini, properti pribadi $name
tersedia di makro:
// user code
A:: macro ( ' concat ' , function ( array $ values ) {
return $ this -> name . ' : ' . implode ( ' - ' , $ values );
} );
( new A )-> concat ( [ ' 1 ' , ' 2 ' , ' 3 ' ] ); // returns 'A:1-2-3'
Makro dapat menggunakan properti sebagai masukan untuk membuat nilai yang dikembalikan.
Paket makro PHP juga memungkinkan untuk mewarisi makro dari kelas induk. Kemudian, mereka dapat mengakses properti kelas dari kelas anak seperti metode kelas biasa:
// original code
class A
{
use Aimeos Macro Macroable;
private $ name = ' A ' ;
};
class B extends A
{
private $ name = ' B ' ;
};
Makro yang ditambahkan ke kelas induk juga akan tersedia di kelas anak:
// user code
A:: macro ( ' concat ' , function ( array $ values ) {
return $ this -> name . ' : ' . implode ( ' - ' , $ values );
} );
( new B )-> concat ( [ ' 1 ' , ' 2 ' , ' 3 ' ] ); // returns 'B:1-2-3'
Kelas B
diturunkan dari kelas A
tetapi menyediakan properti $name
yang berbeda. Makro yang diwarisi dari kelas A
sekarang akan menggunakan properti kelas B
Dimungkinkan juga untuk menimpa makro yang diwarisi dari kelas induk seperti yang dimungkinkan dengan metode kelas reguler:
// original code
class A
{
use Aimeos Macro Macroable;
public function do () {
return static :: macro ( ' concat ' )( [ 1 , 2 , 3 ] );
}
};
class B extends A {};
class C extends A {};
Sekarang Anda bisa menambahkan makro ke kelas induk dan salah satu kelas anak:
// user code
A:: macro ( ' concat ' , function ( array $ values ) {
return implode ( ' , ' , $ values );
} );
C:: macro ( ' concat ' , function ( array $ values ) {
return implode ( ' - ' , $ values );
} );
( new B )-> do (); // returns '1,2,3'
( new C )-> do (); // returns '1-2-3'
Hal ini memungkinkan Anda menambahkan penanganan khusus untuk satu kelas meskipun semua kelas lainnya masih menggunakan makro yang ditambahkan ke kelas A
.
Kelas dasar sering kali menawarkan serangkaian metode yang digunakan oleh kelas turunan. Di PHP, mengganti metode kelas dasar tidak mungkin dilakukan dan oleh karena itu, Anda harus menimpa setiap kelas anak dengan implementasi Anda sendiri.
Untuk menghindari hal tersebut, metode asli dapat menggunakan metode call()
alih-alih memanggil metode kelas induk secara langsung:
// original code
class A
{
use Aimeos Macro Macroable;
protected function getName ( $ prefix )
{
return $ prefix . ' A ' ;
}
};
class B extends A
{
public function do ()
{
return $ this -> call ( ' getName ' , ' B- ' );
}
};
Ini akan memeriksa apakah ada makro getName
yang tersedia dan akan memanggilnya alih-alih metode getName()
:
// user code
( new B )-> do (); // returns 'B-A'
A:: macro ( ' getName ' , function ( $ prefix ) {
return $ this -> getName ( $ prefix ) . ' -123 ' ;
} );
( new B )-> do (); // returns 'B-A-123'
Metode getName()
yang asli masih dapat digunakan di makro.
Terkadang, makro dari objek mungkin perlu dihapus, terutama saat menjalankan pengujian otomatis. Anda dapat menghapus makro dengan menggunakan:
class A
{
use Aimeos Macro Macroable;
};
// add macro
A:: macro ( ' test ' , function () {
return ' test ' ;
} );
// remove macro
A:: unmacro ( ' test ' );