Introduction to WebAssembly and PHP
\n\nWebAssembly (Wasm) is a low-level binary instruction format that runs in a virtual machine with near-native performance. In the context of PHP, it opens up new horizons: you can run code written in C, C++, Rust, or Go directly from a PHP script without leaving the server environment. This is especially useful for resource-intensive tasks — image processing, cryptography, data parsing, or mathematical calculations.
\n\nIn this article, we will cover the full workflow: from compiling source code to Wasm to calling functions from PHP using the wasmtime and wasmer extensions. You will learn how to boost PHP application performance by leveraging the power of machine code.
WebAssembly Basics: What a PHP Developer Needs to Know
\n\nWasm Architecture
\n\nWebAssembly runs in an isolated sandbox. A Wasm module has no direct access to the host's file system, network, or memory — only to its own linear memory and exported functions. This ensures security but requires explicit data management.
\n\nKey concepts:
\n- \n
- Module — a compiled binary file (.wasm) \n
- Exports — functions and variables accessible from outside \n
- Imports — functions that the host (PHP) provides to the module \n
- Linear memory — a contiguous array of bytes that the module operates on \n
Tools for Working with Wasm in PHP
\n\nThere are two main extensions:
\n- \n
- Wasmtime — from Bytecode Alliance, the most popular and stable \n
- Wasmer — an alternative with support for multiple backends (Cranelift, LLVM, Singlepass) \n
Installation via Composer:
\ncomposer require wasmtime/wasmtime-php\n# or\ncomposer require wasmer/wasmer\n\nYou will also need to install the Wasmtime or Wasmer system library. For Ubuntu:
\ncurl https://wasmtime.dev/install.sh -sSf | bash\n# or\ncurl https://get.wasmer.io -sSfL | sh\n\nCompiling C/C++ to WebAssembly
\n\nFor compilation, we use Emscripten — a toolkit based on LLVM/Clang. Installation:
\ngit clone https://github.com/emscripten-core/emsdk.git\ncd emsdk\n./emsdk install latest\n./emsdk activate latest\nsource ./emsdk_env.sh\n\nExample: Sum function in C
\n\nCreate a file math.c:
#include <emscripten.h>\n\nEMSCRIPTEN_KEEPALIVE\nint add(int a, int b) {\n return a + b;\n}\n\nEMSCRIPTEN_KEEPALIVE\nint factorial(int n) {\n if (n <= 1) return 1;\n return n * factorial(n - 1);\n}\n\nCompile to Wasm:
\nemcc math.c -o math.wasm -s WASM=1 -s EXPORTED_FUNCTIONS='["_add","_factorial"]' -s EXPORTED_RUNTIME_METHODS='["ccall","cwrap"]' -O3\n\nThe -O3 flag enables maximum optimization. The math.wasm file is ready for use.
Integrating Wasm with PHP: Step-by-Step Examples
\n\nScenario 1: Using Wasmtime
\n\nInstall the extension and write the following PHP code:
\n<?php\nrequire 'vendor/autoload.php';\n\nuse Wasmtime\\Engine;\nuse Wasmtime\\Module;\nuse Wasmtime\\Store;\nuse Wasmtime\\Func;\nuse Wasmtime\\Val;\n\n// Load the module\n$engine = new Engine();\n$module = Module::fromFile($engine, 'math.wasm');\n$store = new Store($engine);\n\n// Create an instance\n$instance = new Wasmtime\\Instance($store, $module, []);\n\n// Get the exported function\n$add = $instance->getExport($store, 'add');\n$factorial = $instance->getExport($store, 'factorial');\n\n// Call the functions\n$resultAdd = $add->call($store, 5, 7);\n$resultFact = $factorial->call($store, 10);\n\necho "5 + 7 = " . $resultAdd[0]->i32() . "\\n"; // 12\necho "10! = " . $resultFact[0]->i32()