This repository is a small collection of examples that embed PHP into a C program through the embed SAPI and use PHP's Stream API to handle HTTP communication.
The examples show how to bootstrap an embedded PHP runtime from C without writing PHP scripts, then directly use APIs such as php_stream_xport_create(), php_stream_read(), and php_stream_write().
src/http_client.cConnects toexample.com:80over TCP, sends an HTTP/1.1 GET request, and prints the full response to standard output.src/http_server.cA minimal HTTP server that listens on127.0.0.1:8080, logs the received request, and returnshello world.src/http_server_tls.cA minimal HTTPS server that listens on127.0.0.1:8443. It configures SSL options through a PHP stream context and is intended for local experiments with self-signed certificates.
- A PHP development environment with the
embedSAPI enabled - PHP header files
- A shared
libphplibrary - A C compiler
If php-config --php-sapis includes embed, that is a good sign that embedded PHP support is available.
On Debian / Ubuntu systems, you may need packages equivalent to php8.x-dev and libphp8.x-embed. The actual library name depends on your environment, so check /usr/lib/libphp*.so and the output of php-config.
This repository does not include a Makefile. The intended starting point is to compile each example individually.
In this environment, at least src/http_client.c and src/http_server.c built successfully with the following pattern.
cc -o http_client src/http_client.c $(php-config --includes) $(php-config --ldflags) -L/usr/lib -lphp8.5
cc -o http_server src/http_server.c $(php-config --includes) $(php-config --ldflags) -L/usr/lib -lphp8.5
cc -o http_server_tls src/http_server_tls.c $(php-config --includes) $(php-config --ldflags) -L/usr/lib -lphp8.5Depending on your system, -lphp8.5 may need to be replaced with something like -lphp8.4, -lphp8, or -lphp. Some environments also return an empty value from php-config --lib-embed, so adjust the link target to match the actual library file you have installed.
./http_clientThis prints the full HTTP response returned by example.com.
./http_server
curl -i http://127.0.0.1:8080/The server logs the raw request and returns the following response body to the client.
hello world
src/http_server_tls.c assumes that the following files exist in the current working directory.
localhost.pemlocalhost-key.pem
For local testing, a self-signed certificate can be generated like this.
openssl req -x509 -newkey rsa:2048 -nodes -keyout localhost-key.pem -out localhost.pem -subj "/CN=localhost" -days 365Start the server and test it like this.
./http_server_tls
curl -k -i https://127.0.0.1:8443/This example intentionally sets allow_self_signed=true, verify_peer=false, and verify_peer_name=false to make local testing easier. These settings are not suitable for production.
- The minimum setup required to initialize and shut down embedded PHP from C
- Creating client and server transports with
php_stream_xport_create() - Configuring SSL options with
php_stream_context_set_option() - Building HTTP messages with
smart_str - The general feel of using PHP's Stream API directly from C
- These examples are for learning and experimentation. They intentionally omit the robustness and security work required by production-grade HTTP software.
- The server implementations only read a single request in a very simple way. They do not handle keep-alive, partial reads, timeout management, or similar concerns.
- The TLS example assumes the use of a self-signed certificate.