Migrating to v0.14
New Macro Transition
The old macro system used a global state to be able to automatically register
functions and classes when the #[php_module]
attribute is used. However,
global state can cause problems with incremental compilation and is not
recommended.
To solve this, the macro system has been re-written but this will require changes to user code. This document summarises the changes.
There is no real changes on existing macros, however you will now need to register functions, classes, constants and startup function when declaring the module.
#[php_module(startup = "startup_function")]
pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
module
.class::<TestClass>()
.function(wrap_function!(hello_world))
.constant(wrap_constant!(SOME_CONSTANT))
}
Functions
Mostly unchanged in terms of function definition, however you now need to register the function with the module builder:
use ext_php_rs::prelude::*;
#[php_function]
pub fn hello_world() -> &'static str {
"Hello, world!"
}
#[php_module]
pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
module
.function(wrap_function!(hello_world))
}
Classes
Mostly unchanged in terms of the class and impl definitions, however you now need to register the classes with the module builder:
use ext_php_rs::prelude::*;
#[php_class]
#[derive(Debug)]
pub struct TestClass {
#[prop]
a: i32,
#[prop]
b: i32,
}
#[php_impl]
impl TestClass {
#[rename("NEW_CONSTANT_NAME")]
pub const SOME_CONSTANT: i32 = 5;
pub const SOME_OTHER_STR: &'static str = "Hello, world!";
pub fn __construct(a: i32, b: i32) -> Self {
Self { a: a + 10, b: b + 10 }
}
#[optional(test)]
#[defaults(a = 5, test = 100)]
pub fn test_camel_case(&self, a: i32, test: i32) {
println!("a: {} test: {}", a, test);
}
fn x(&self) -> i32 {
5
}
pub fn builder_pattern(
self_: &mut ZendClassObject<TestClass>,
) -> &mut ZendClassObject<TestClass> {
dbg!(self_)
}
}
#[php_module]
pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
module
.class::<TestClass>()
}
Constants
Mostly unchanged in terms of constant definition, however you now need to register the constant with the module builder:
use ext_php_rs::prelude::*;
#[php_const]
const SOME_CONSTANT: i32 = 100;
#[php_module]
pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
module
.constant(wrap_constant!(SOME_CONSTANT)) // SOME_CONSTANT = 100
.constant(("CONST_NAME", SOME_CONSTANT, &[])) // CONST_NAME = 100
}
Extern
No changes.
use ext_php_rs::prelude::*;
#[php_extern]
extern "C" {
fn phpinfo() -> bool;
}
fn some_rust_func() {
let x = unsafe { phpinfo() };
println!("phpinfo: {x}");
}
Startup Function
The #[php_startup]
macro has been deprecated. Instead, define a function with
the signature fn(ty: i32, mod_num: i32) -> i32
and provide the function name
use ext_php_rs::prelude::*;
fn startup_function(ty: i32, mod_num: i32) -> i32 {
0
}
#[php_module(startup = "startup_function")]
pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
module
}