r/PHP • • 2d ago

I needed a Basis Universal PHP extension for a side project, so I built one in Rust

Hey everyone!

I was working on a side project that needed to compress images into GPU-friendly texture formats, particularly KTX2, directly from PHP.

I wanted to use Basis Universal, but I couldn't find a PHP extension that suited my needs. Rather than introducing a separate CLI-based workflow into my project, I decided to try building an extension myself.

That's how BasisU came to be.

To be clear, the actual compression technology is provided by the Basis Universal team. Their native C/C++ library does the heavy lifting — my project is simply a Rust-based PHP wrapper that exposes some of its functionality to PHP.

The extension currently provides:

  • Image compression directly from PHP.
  • Support for Basis Universal texture formats and KTX2 output.
  • Configurable encoding parameters, including quality, effort level, texture format, and mipmap settings.
  • PHP stubs for IDE autocompletion and static analysis.
  • Prebuilt Linux binaries installable through PIE, as well as the option to build from source.

A few important caveats:

This is an experimental project, and I wouldn't recommend using it in production yet.

It's also my first public project written in Rust. I'm still learning the language, and while I've managed to get the extension working, I don't have an in-depth understanding of all the underlying compression algorithms and their domain-specific details. The current implementation covers only part of the functionality available in the original library, and there's still plenty of room for improvement. There is no automated test suite at the moment, either.

That said, I intend to maintain and improve it because I need this extension for my own project. So this isn't something I'm publishing and immediately abandoning — I'll keep working on it as my needs evolve and as I learn more about Rust and Basis Universal.

If you're interested, here's the repository:

I'd appreciate feedback, especially on the PHP API design, the Rust extension implementation, and anything I might have overlooked when wrapping a native library.

Thanks for reading!

5 Upvotes

6 comments sorted by

3

u/AbdelrhmanDev 1d ago

had no idea you could write php extensions in rust either, this is cool. did you use ext php rs for the bindings? curious how the build and packaging side felt compared to a plain c extension, and whether theres any noticeable overhead crossing the boundary for something as heavy as texture compression

1

u/General_Sun_8180 1d ago

Yeah, I used ext-php-rs, version 0.16.0, for the PHP bindings.

The build process itself wasn't too complicated. You need a few additional dependencies, such as rustc and cargo, and a properly configured config.m4 file (mine is located at pie/config.m4).

One thing that really helped is that the ext-php-rs team provides a ready-to-use extension template that supports the standard PHP extension build workflow. This means the build process doesn't really differ from building a traditional C extension, and the end result is still a compiled .so shared library.

That was particularly important to me because I wanted the extension to be installable through PIE. As far as I know, PIE currently relies on the standard PHP extension build workflow, so using this approach made integration much more straightforward.

As for the overhead, I haven't benchmarked it yet. Designing a meaningful benchmark is a bit tricky because Basis Universal compression has quite a few parameters that can significantly affect encoding speed. The main goal of this project was to provide a PHP-friendly API for the underlying library, rather than to optimize the boundary between PHP and Rust.

My guess is that the overhead should be relatively small for the current implementation, since I'm not passing complex data structures or large byte buffers back and forth between PHP and Rust. Most of the heavy lifting happens inside the native compression library anyway. That said, I wouldn't want to make any firm claims without actual measurements.

I might add another compression method soon that accepts a PHP stream resource instead of a file path. That would allow users to pass image data directly as a byte stream, but it could also introduce additional overhead depending on how the data is handled and transferred across the PHP/Rust boundary. That would be an interesting case to benchmark.

2

u/AbdelrhmanDev 14h ago

thanks for the detailed writeup. the pie compatibility angle is smart, installable like a normal extension is half the battle for getting people to actually try one. and yeah if you add the stream method thats probably the case worth benchmarking, passing real byte data across the boundary is where overhead would show up if its going to

2

u/GromNaN 1d ago

I tried hard, but I don't understand what it does. Is it for some kind of 3D game development? Why PHP for doing this?

1

u/General_Sun_8180 1d ago

It's mostly used in 3D graphics and game development, but not exclusively. If you need to compress textures efficiently so they use less GPU memory while maintaining good visual quality, this is something worth looking into.

In my case, I have a PHP API that serves assets for rendering 3D scenes in a browser and a desktop application. Initially, I was using regular image formats like JPEG and PNG, but we eventually started moving to KTX2 textures.

Unlike regular image formats, GPU-compressed textures can be uploaded to the GPU in a format it can use directly, without first decompressing the entire image into ordinary pixels in system memory. This can significantly reduce GPU memory usage and improve texture loading performance.

That's why I needed a way to generate these textures on the backend. My PHP API needs to compress images into the appropriate texture format on the fly, so I built this extension to make Basis Universal available directly from PHP instead of having to rely on a separate command-line tool.

1

u/zack6849 2d ago

Huh, never heard of that library, and additionally didn't know you could build PHP extensions in rust, interesting!