Skip to content

Instantly share code, notes, and snippets.

@masakielastic
Last active March 21, 2026 20:40
Show Gist options
  • Select an option

  • Save masakielastic/2e4dbad682d8f0d0097ed0b393872346 to your computer and use it in GitHub Desktop.

Select an option

Save masakielastic/2e4dbad682d8f0d0097ed0b393872346 to your computer and use it in GitHub Desktop.
embed PHP と Stream API で HTTP/1 クライアント。最新版は https://github.com/masakielastic/php-embed-stream-http
#include <php.h>
#include <Zend/zend_smart_str.h>
#include <sapi/embed/php_embed.h>
#include <main/php_streams.h>
static int run_min_client(void);
int main(int argc, char **argv)
{
PHP_EMBED_START_BLOCK(argc, argv)
(void) run_min_client();
PHP_EMBED_END_BLOCK()
return 0;
}
static int run_min_client(void)
{
php_stream *stream = NULL;
zend_string *target = NULL;
zend_string *request = NULL;
zend_string *errstr = NULL;
smart_str response = {0};
char buf[4096];
ssize_t nread;
int err = 0;
const char *host = "example.com";
const int port = 80;
target = strpprintf(0, "tcp://%s:%d", host, port);
if (target == NULL) {
php_printf("failed to build target\n");
return FAILURE;
}
stream = php_stream_xport_create(
ZSTR_VAL(target),
ZSTR_LEN(target),
REPORT_ERRORS,
STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT,
NULL,
NULL,
NULL,
&errstr,
&err
);
if (stream == NULL) {
php_printf(
"connect failed: err=%d msg=%s\n",
err,
errstr ? ZSTR_VAL(errstr) : "(none)"
);
if (errstr) {
zend_string_release(errstr);
}
zend_string_release(target);
return FAILURE;
}
request = strpprintf(
0,
"GET / HTTP/1.1\r\n"
"Host: %s\r\n"
"User-Agent: embed-php-stream-client/0.1\r\n"
"Accept: */*\r\n"
"Connection: close\r\n"
"\r\n",
host
);
if (request == NULL) {
php_printf("failed to build request\n");
php_stream_close(stream);
zend_string_release(target);
return FAILURE;
}
if (php_stream_write(stream, ZSTR_VAL(request), ZSTR_LEN(request)) != (ssize_t) ZSTR_LEN(request)) {
php_printf("write failed\n");
zend_string_release(request);
php_stream_close(stream);
zend_string_release(target);
return FAILURE;
}
while ((nread = php_stream_read(stream, buf, sizeof(buf))) > 0) {
smart_str_appendl(&response, buf, nread);
}
smart_str_0(&response);
if (response.s) {
php_printf("=== response begin ===\n");
PHPWRITE(ZSTR_VAL(response.s), ZSTR_LEN(response.s));
php_printf("\n=== response end ===\n");
} else {
php_printf("no response\n");
}
smart_str_free(&response);
zend_string_release(request);
php_stream_close(stream);
zend_string_release(target);
return SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment