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/objdumpWhen 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
structfrom 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
Enjoyed this article? Share it with someone who'd love it too.