Foreign Function Interface (FFI) lets PHP call C functions and read/write C data structures directly from userland. Instead of waiting for a PHP extension to be compiled and installed, you can bind to an existing shared library (.so
, .dylib
, .dll
) at runtime and use it immediately.
This unlocks three big wins:
⚠️ Safety: FFI can crash the PHP process if you misdeclare a function or misuse pointers. Use it thoughtfully in CLI tools and background workers first; restrict or disable in shared web runtimes.
FFI::cdef($cHeader, $libName)
.FFI::new
, FFI::array
), pass pointers to functions, and convert results back to PHP with helpers like FFI::string()
.sysinfo(2)
(not a built‑in PHP function)PHP doesn't expose the full sysinfo
syscall, but the C library does. With FFI you can read uptime, loads, RAM and swap totals in one call.
<?php
// sysinfo: declared in <sys/sysinfo.h> and provided by libc
$ffi = FFI::cdef(<<<'CDEF'
typedef long time_t;
typedef unsigned long __kernel_ulong_t;
struct sysinfo {
long uptime; // Seconds since boot
unsigned long loads[3]; // 1, 5, 15 minute load averages (fixed‑point 1/65536)
unsigned long totalram; // Total usable main memory size
unsigned long freeram; // Available memory size
unsigned long sharedram; // Amount of shared memory
unsigned long bufferram; // Memory used by buffers
unsigned long totalswap; // Total swap space size
unsigned long freeswap; // Swap space still available
unsigned short procs; // Number of current processes
unsigned long totalhigh; // Total high memory size
unsigned long freehigh; // Available high memory size
unsigned int mem_unit; // Memory unit size in bytes
char _f[20-2*sizeof(long)-sizeof(int)]; // Padding to 64 bytes
};
int sysinfo(struct sysinfo *info);
CDEF, "libc.so.6");
$info = $ffi->new("struct sysinfo");
if ($ffi->sysinfo(FFI::addr($info)) !== 0) {
throw new RuntimeException("sysinfo() failed");
}
$scale = 65536.0;
$load1 = $info->loads[0] / $scale;
$load5 = $info->loads[1] / $scale;
$load15 = $info->loads[2] / $scale;
$bytes = fn(int $n) => $n * $info->mem_unit;
printf(
"Uptime: %d s, Loads: %.2f, %.2f, %.2f\nRAM: %.1f GB total, %.1f GB free\n",
$info->uptime, $load1, $load5, $load15,
$bytes($info->totalram)/1e9, $bytes($info->freeram)/1e9
);
Why this is useful: a single, fast syscall gives you host health without shelling out or parsing /proc
files.
erf
/erfc
from libm
(not in core PHP)PHP lacks error function helpers common in stats/signal processing. Bind to the math library instead:
<?php
$ffi = FFI::cdef(<<<'CDEF'
double erf(double x);
double erfc(double x);
CDEF, "libm.so.6");
$z = 1.0;
printf("erf(%f) = %.6f\n", $z, $ffi->erf($z));
printf("erfc(%f) = %.6f\n", $z, $ffi->erfc($z));
Use cases: Gaussian CDFs, diffusion models, and numerical methods that rely on erf
/erfc
.
cdef
: Using nm
/readelf
/objdump
When a function isn't documented in PHP, you need to confirm its symbol name and signature. Three handy tools on Linux:
nm -D /path/to/lib.so
-- lists dynamic symbols (exported functions/vars)readelf -Ws /path/to/lib.so
-- ELF symbol table with sizes/bindingsobjdump -T /path/to/lib.so
-- dynamic symbol tableLocate the library
ldconfig -p | grep -E 'libm|libc|yourlib'
List symbols
nm -D /lib/x86_64-linux-gnu/libm.so.6 | grep -E 'erf|erfc'
# or:
readelf -Ws /lib/x86_64-linux-gnu/libm.so.6 | grep erf
You'll see something like _Z...
for C++ (mangled) or plain erf
. Prefer C symbols (unmangled).
Confirm the signature in headers/man pages
man 3 erf
, or read /usr/include/math.h
to copy the declaration exactly.FFI::cdef(...)
block.Test with safe inputs and add runtime guards in PHP.
Tip: for complex structs, copy the exact C
struct
from the header into yourcdef
. Field order and sizes must match your platform's headers.
libc.so.6
/ macOS libSystem.B.dylib
/ Windows msvcrt.dll
or specific vendor DLLs.cdef
text.sysinfo
and erf/erfc
right now.nm
/readelf
/objdump
to discover symbol names, then confirm the exact signature in headers/man pages.If PHP has felt limited before, FFI will change how you think about "what PHP can do." It's a bridge to native power--use it wisely and it will make your applications feel faster and more capable.
Ready to dive deeper? Check out our advanced section