22use ext_php_rs:: {
33 binary:: Binary ,
44 boxed:: ZBox ,
5+ convert:: IntoZval ,
56 prelude:: * ,
67 types:: { ArrayKey , ZendHashTable , ZendObject , Zval } ,
78 zend:: ProcessGlobals ,
@@ -210,6 +211,10 @@ impl TestClass {
210211 pub fn set_number ( & mut self , number : i32 ) {
211212 self . number = number;
212213 }
214+
215+ pub fn static_call ( name : String ) -> String {
216+ format ! ( "Hello {name}" )
217+ }
213218}
214219
215220#[ php_function]
@@ -221,10 +226,100 @@ pub fn test_class(string: String, number: i32) -> TestClass {
221226 }
222227}
223228
229+ #[ php_class]
230+ pub struct MagicMethod ( i64 ) ;
231+
232+ #[ php_impl]
233+ impl MagicMethod {
234+ pub fn __construct ( ) -> Self {
235+ Self ( 0 )
236+ }
237+
238+ pub fn __destruct ( & self ) { }
239+
240+ pub fn __call ( & self , name : String , _arguments : HashMap < String , & Zval > ) -> Zval {
241+ let mut z = Zval :: new ( ) ;
242+ if name == "callMagicMethod" {
243+ let s = "Hello" . to_string ( ) ;
244+
245+ let _ = z. set_string ( s. as_str ( ) , false ) ;
246+ z
247+ } else {
248+ z. set_null ( ) ;
249+ z
250+ }
251+ }
252+
253+ pub fn __call_static ( name : String , arguments : HashMap < String , & Zval > ) -> Zval {
254+ let mut zval = Zval :: new ( ) ;
255+ if name == "callStaticSomeMagic" {
256+ let concat_args = format ! (
257+ "Hello from static call {}" ,
258+ arguments
259+ . iter( )
260+ . filter( |( _, v) | v. is_long( ) )
261+ . map( |( _, s) | s. long( ) . unwrap( ) . to_string( ) )
262+ . collect:: <Vec <_>>( )
263+ . join( " " )
264+ ) ;
265+
266+ let _ = zval. set_string ( & concat_args, false ) ;
267+ zval
268+ } else {
269+ zval. set_null ( ) ;
270+ zval
271+ }
272+ }
273+
274+ pub fn __get ( & self , name : String ) -> Zval {
275+ let mut v = Zval :: new ( ) ;
276+ v. set_null ( ) ;
277+ if name == "count" {
278+ v. set_long ( self . 0 ) ;
279+ }
280+
281+ v
282+ }
283+
284+ pub fn __set ( & mut self , prop_name : String , val : & Zval ) {
285+ if val. is_long ( ) && prop_name == "count" {
286+ self . 0 = val. long ( ) . unwrap ( )
287+ }
288+ }
289+
290+ pub fn __isset ( & self , prop_name : String ) -> bool {
291+ "count" == prop_name
292+ }
293+
294+ pub fn __unset ( & mut self , prop_name : String ) {
295+ if prop_name == "count" {
296+ self . 0 = 0 ;
297+ }
298+ }
299+
300+ pub fn __to_string ( & self ) -> String {
301+ self . 0 . to_string ( )
302+ }
303+
304+ pub fn __invoke ( & self , n : i64 ) -> i64 {
305+ self . 0 + n
306+ }
307+
308+ pub fn __debug_info ( & self ) -> HashMap < String , Zval > {
309+ let mut h: HashMap < String , Zval > = HashMap :: new ( ) ;
310+ let mut z = Zval :: new ( ) ;
311+ z. set_long ( self . 0 ) ;
312+ h. insert ( "count" . to_string ( ) , z) ;
313+
314+ h
315+ }
316+ }
317+
224318#[ php_module]
225319pub fn build_module ( module : ModuleBuilder ) -> ModuleBuilder {
226320 module
227321 . class :: < TestClass > ( )
322+ . class :: < MagicMethod > ( )
228323 . function ( wrap_function ! ( test_str) )
229324 . function ( wrap_function ! ( test_string) )
230325 . function ( wrap_function ! ( test_bool) )
@@ -317,6 +412,7 @@ mod integration {
317412 mod closure;
318413 mod globals;
319414 mod iterator;
415+ mod magic_method;
320416 mod nullable;
321417 mod number;
322418 mod object;
0 commit comments