devrustphp
~3 min (401 words)

Rusty PHP - creating PHP extensions with Rust

A modified and modernized ElePHPant PHP mascot in a rusty color

Recently, I took a look at the ext-php-rs project.

With ext-php-rs you can very easily write extensions for PHP in Rust.

So, for testing, I developed a little extension implementing a function I recently used in native PHP.


Why using a native PHP function for comparison you asked?

For three reasons:

  1. Check the performance impact using an external Rust implementation compared to PHP native functions
  2. Get an idea about how to develop an extension with ext-php-rs
  3. See how comfortable it is to do that

Setting up ext-php-rs

If you have used Rust before, it's really very straightforward:

  1. Install PHP executable and the development packages
  2. Create a new Rust project via cargo new php-ext --lib
  3. Now open the project in an IDE like RustRover or IntelliJ Community or whatever
  4. Make sure the Cargo.toml looks is configured like this
[lib]
crate-type = ["cdylib"]

[dependencies]
ext-php-rs = "*"

[profile.release]
strip = "debuginfo"

Now we still need the cargo subcommand to run the php extensions:

cargo install cargo-php

Via cargo php you can now install or delete extensions directly into your PHP environment.

The lib.rs can now look as simple as this:


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

use ext_php_rs::prelude::*;

#[php_function]
pub fn find_mapping(needle: String, haystack: Vec<String>) -> Option<String> {
    haystack.iter().find(|&elem| elem == &needle).cloned()
}

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



A simple cargo build and cargo php install will enable you to use the function in any php file:

find_mapping($testString, $randomStrings);



Conclusion

Setting up the ext-php-rs project is very straightforward and knowing a bit of Rust you can create a new PHP extension in almost no time.

Also, most things can be done quite fine with better performance by native PHP functions so such an extension is especially suited for apps with compute intense processes or safety concerns that can be modularized into an extension. Yes, I did some simple benchmarks here. Will try to add them later.

And you have to look at this adorable slightly rusty ElePHPant: arewefuckedyet.com's doomsday clock



Image Attribution
Both images created by ideogram.ai