MCPcopy Index your code
hub / github.com/extphprs/ext-php-rs

github.com/extphprs/ext-php-rs @ext-php-rs-v0.15.15

Chat with this repo
repository ↗ · DeepWiki ↗ · release ext-php-rs-v0.15.15 ↗ · + Follow
2,170 symbols 5,519 edges 208 files 478 documented · 22%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

ext-php-rs

Crates.io docs.rs Guide Workflow Status CI Workflow Status Coverage Status Discord

Bindings and abstractions for the Zend API to build PHP extensions natively in Rust.

Example

Export a simple function function hello_world(string $name): string to PHP:

#![cfg_attr(windows, feature(abi_vectorcall))]

use ext_php_rs::prelude::*;

/// Gives you a nice greeting!
///
/// @param string $name Your name.
///
/// @return string Nice greeting!
#[php_function]
pub fn hello_world(name: String) -> String {
    format!("Hello, {}!", name)
}

// Required to register the extension with PHP.
#[php_module]
pub fn module(module: ModuleBuilder) -> ModuleBuilder {
    module.function(wrap_function!(hello_world))
}

Use [cargo-php] to build IDE stubs and install the extension:

$ cargo install cargo-php --locked
  Installing cargo-php v0.1.0
$ cargo php stubs --stdout
  Compiling example-ext v0.1.0
  Finished dev [unoptimized + debuginfo] target(s) in 3.57s
<?php

// Stubs for example-ext

/**
 * Gives you a nice greeting!
 *
 * @param string $name Your name.
 *
 * @return string Nice greeting!
 */
function hello_world(string $name): string {}
$ cargo php install --release
  Compiling example-ext v0.1.0
  Finished release [optimized] target(s) in 1.68s
Are you sure you want to install the extension `example-ext`? yes
$ php -m
[PHP Modules]
// ...
example-ext
// ...

Calling the function from PHP:

var_dump(hello_world("David")); // string(13) "Hello, David!"

For more examples read the library guide.

Features

  • Easy to use: The built-in macros can abstract away the need to interact with the Zend API, such as Rust-type function parameter abstracting away interacting with Zend values.
  • Lightweight: You don't have to use the built-in helper macros. It's possible to write your own glue code around your own functions.
  • Extensible: Implement IntoZval and FromZval for your own custom types, allowing the type to be used as function parameters and return types.

Goals

Our main goal is to make extension development easier.

  • Writing extensions in C can be tedious, and with the Zend APIs limited documentation can be intimidating.
  • Rust's modern language features and feature-full standard library are big improvements on C.
  • Abstracting away the raw Zend APIs allows extensions to be developed faster and with more confidence.
  • Abstractions also allow us to support future (and potentially past) versions of PHP without significant changes to extension code.

Documentation

The library guide can be read here.

The project is documented in-line, so viewing the cargo documentation is the best resource at the moment. This can be viewed at docs.rs.

Requirements

  • Linux, macOS or Windows-based operating system.
  • PHP 8.1 or later.
  • No support is planned for earlier versions of PHP.
  • PHP versions, that no longer receive security updates, will no longer be supported. They might still work, but no guarantees are made.
  • See https://www.php.net/supported-versions.php for information on PHP supported versions and their end of life dates.
  • Rust.
  • Currently, we maintain no guarantee of a MSRV, however lib.rs suggests Rust 1.57 at the time of writing.
  • Clang 5.0 or later.

Alpine Linux (musl)

Building on Alpine Linux (musl libc) is supported thanks to the runtime feature flag.

# Install dependencies and cargo-php
apk add clang16-libclang
cargo install cargo-php

When building your own extensions, add to your project's .cargo/config.toml:

[target.'cfg(target_env = "musl")']
rustflags = ["-C", "target-feature=-crt-static"]

For static linking, see: https://github.com/KyleMayes/clang-sys#static

Windows Requirements

  • Extensions can only be compiled for PHP installations sourced from https://windows.php.net. Support is planned for other installations eventually.
  • Rust nightly is required for Windows. This is due to the vectorcall calling convention being used by some PHP functions on Windows, which is only available as a nightly unstable feature in Rust.
  • It is suggested to use the rust-lld linker to link your extension. The MSVC linker (link.exe) is supported however you may run into issues if the linker version is not supported by your PHP installation. You can use the rust-lld linker by creating a .cargo\config.toml file with the following content: toml # Replace target triple if you have a different architecture than x86_64 [target.x86_64-pc-windows-msvc] linker = "rust-lld"
  • The cc crate requires cl.exe to be present on your system. This is usually bundled with Microsoft Visual Studio.
  • cargo-php's stub generation feature does not work on Windows. Rewriting this functionality to be cross-platform is on the roadmap.
  • To build the application in DEBUG mode on Windows, you must have a PHP SDK built with the DEBUG option enabled and specify the PHP_LIB to the folder containing the lib files. For example: set PHP_LIB=C:\php-sdk\php-dev\vc16\x64\php-8.3.13-src\x64\Debug_TS.

Cargo Features

All features are disabled by default.

  • closure - Enables the ability to return Rust closures to PHP. Creates a new class type, RustClosure.
  • anyhow - Implements Into<PhpException> for anyhow::Error, allowing you to return anyhow results from PHP functions. Supports anyhow v1.x.
  • static - Allows building the library against statically linked clang, for example with static-php-cli

Usage

Check out the awesome-ext-php-rs list for projects built with ext-php-rs.

Contributions

We welcome contributions to the project! Please see the CONTRIBUTING.md file for more information on how to contribute.

Development

allowed_bindings.rs

This file contains the list of allowed bindings for the Zend API. It is acting as a whitelist for the bindings that can be used in the library.

When updating this file you need to also update the docsrs_bindings.rs file. To do this, run the following command from the root of the project:

tools/update_bindings.sh

This will build the bindings using docker, and then copy the docsrs_bindings.rs file to the root of the repository. This will ensure that the file is always built in the same environment.

Docker and buildx are required to run the script, so make sure you have those installed.

Resources

License

Licensed under either of

at your option.

Extension points exported contracts — how you extend this code

RegisteredClass (Interface)
Implemented on Rust types which are exported to PHP. Allows users to get and set PHP properties on the object. [7 implementers]
src/class.rs
FromZval (Interface)
Allows zvals to be converted into Rust types in a fallible way. Reciprocal of the [`IntoZval`] trait. [28 implementers]
src/convert.rs
ToStub (Interface)
Implemented on types which can be converted into PHP stubs. [12 implementers]
src/describe/stub.rs
DropLifetimes (Interface)
Implemented on syn types which can contain lifetimes. [21 implementers]
crates/macros/src/syn_ext.rs
ZBoxable (Interface)
Implemented on types that can be heap allocated using the Zend memory manager. These types are stored inside a [`ZBox`] [4 …
src/boxed.rs
FcallObserver (Interface)
Trait for observing PHP function calls. # Lifecycle 1. `should_observe` is called once per unique function (cached by [4 …
src/zend/observer.rs
RegisteredEnum (Interface)
Implemented on Rust enums which are exported to PHP. [3 implementers]
src/enum_.rs
IntoConst (Interface)
Implemented on types which can be registered as a constant in PHP. [3 implementers]
src/constant.rs

Core symbols most depended-on inside this repo

insert
called by 203
src/types/array/mod.rs
function
called by 139
src/zend/ex.rs
run
called by 137
crates/cli/src/lib.rs
iter
called by 116
src/types/iterable.rs
len
called by 103
src/types/array/mod.rs
is_null
called by 85
src/types/zval.rs
push
called by 75
src/types/array/mod.rs
arg
called by 68
src/args.rs

Shape

Method 960
Function 826
Class 301
Interface 42
Enum 41

Languages

Rust97%
PHP2%
C1%

Modules by API surface

docsrs_bindings.rs182 symbols
src/types/zval.rs91 symbols
tests/src/integration/class/mod.rs76 symbols
src/builders/sapi.rs72 symbols
tests/src/integration/observer/mod.rs66 symbols
src/zend/globals.rs52 symbols
src/zend/zend_extension.rs48 symbols
src/zend/ce.rs38 symbols
src/args.rs37 symbols
src/types/object.rs36 symbols
src/types/array/mod.rs36 symbols
crates/macros/src/parsing.rs36 symbols

For agents

$ claude mcp add ext-php-rs \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page