#[php_module]Expand description
§#[php_module] Attribute
The module macro is used to annotate the get_module function, which is
used by the PHP interpreter to retrieve information about your extension,
including the name, version, functions and extra initialization functions.
Regardless if you use this macro, your extension requires a extern "C" fn get_module() so that PHP can get this information.
The function is renamed to get_module if you have used another name. The
macro also exports a crate-prefixed <crate_name>_get_module alias, used
when statically linking the extension into
php-src. Building with
EXT_PHP_RS_STATIC_EXT=1 removes the unmangled get_module export (the
function itself stays callable from Rust) so a statically linked
extension cannot collide with another extension exporting get_module.
Dynamic builds (extension= / dl()) must not set the variable.
The function is passed an instance of ModuleBuilder which allows you to
register the following (if required):
- Functions, classes, and constants
- Extension and request startup and shutdown functions.
- Read more about the PHP extension lifecycle here.
- PHP extension information function
- Used by the
phpinfo()function to get information about your extension.
- Used by the
Classes and constants are not registered with PHP in the get_module
function. These are registered inside the extension startup function.
§Startup failures
If a constant, an interface, a class or an enum cannot be registered, the
generated startup function logs the cause as an E_CORE_WARNING and returns
FAILURE. PHP then reports Unable to start <extension> module. At engine
startup PHP exits. From dl() the request fails. A panic during
registration gets the same treatment. The process does not abort in either
case.
get_module cannot report a failure, because PHP reads the returned entry
without a check. If the ModuleBuilder cannot become a module entry, for
example because a function name, an argument name or the module name
contains a NUL byte, the macro returns a placeholder entry with the name of
the crate. The startup function of that entry logs the build error and fails
as described above.
The startup function that you name in #[php(startup = ...)] is your own
extern "C" function. A panic inside it is not caught.
You can also give a startup function to ModuleBuilder::startup_function.
The generated startup function calls it after the #[php(startup = ...)]
function. The two functions run before the macro registers the constants,
interfaces, classes and enums.
§Usage
use ext_php_rs::{
prelude::*,
zend::ModuleEntry,
info_table_start,
info_table_row,
info_table_end
};
#[php_const]
pub const MY_CUSTOM_CONST: &'static str = "Hello, world!";
#[php_class]
pub struct Test {
a: i32,
b: i32
}
#[php_function]
pub fn hello_world() -> &'static str {
"Hello, world!"
}
/// Used by the `phpinfo()` function and when you run `php -i`.
/// This will probably be simplified with another macro eventually!
pub extern "C" fn php_module_info(_module: *mut ModuleEntry) {
info_table_start!();
info_table_row!("my extension", "enabled");
info_table_end!();
}
#[php_module]
pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
module
.constant(wrap_constant!(MY_CUSTOM_CONST))
.class::<Test>()
.function(wrap_function!(hello_world))
.info_function(php_module_info)
}