Skip to main content

php_impl_interface

Attribute Macro php_impl_interface 

Source
#[php_impl_interface]
Expand description

§#[php_impl_interface] Attribute

Marks a trait implementation as implementing a PHP interface. This allows Rust structs marked with #[php_class] to implement Rust traits marked with #[php_interface], and have PHP recognize the relationship.

Key feature: The macro automatically registers the trait methods as PHP methods on the class. You don’t need to duplicate them in a separate #[php_impl] block.

§Usage

use ext_php_rs::prelude::*;

#[php_interface]
trait MyInterface {
    fn my_method(&self) -> String;
}

#[php_class]
struct MyClass;

// The trait method my_method() is automatically registered as a PHP method
#[php_impl_interface]
impl MyInterface for MyClass {
    fn my_method(&self) -> String {
        "Hello from MyClass!".to_string()
    }
}

#[php_module]
pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
    module
        .interface::<PhpInterfaceMyInterface>()
        .class::<MyClass>()
}

After registration, PHP’s is_a($obj, 'MyInterface') will return true for instances of MyClass, and $obj->myMethod() will be callable.

§Options

§change_method_case

If the interface uses a non-default change_method_case (e.g., #[php(change_method_case = "snake_case")]), you must specify the same setting on #[php_impl_interface] to ensure method names match:

#[php_interface]
#[php(change_method_case = "snake_case")]
trait MyInterface {
    fn my_method(&self) -> String;
}

#[php_impl_interface(change_method_case = "snake_case")]
impl MyInterface for MyClass {
    fn my_method(&self) -> String {
        "Hello!".to_string()
    }
}

The default is camelCase (matching the interface default).

§Requirements

  • The trait must be marked with #[php_interface]
  • The struct must be marked with #[php_class]
  • The interface must be registered before the class in the module builder