A context passes options to a wrapper, such as the method, headers, body and timeout for http://. Build it with stream_context_create() and pass it to file_get_contents() or fopen(). The client starts PHP's built-in server on this endpoint itself:
<?php
http_response_code($_SERVER['REQUEST_METHOD'] === 'POST' ? 201 : 405);
echo json_encode(['type' => $_SERVER['CONTENT_TYPE'] ?? null,
'body' => json_decode(file_get_contents('php://input'), true)]);<?php
declare(strict_types=1);
$quiet = [1 => ['file', '/dev/null', 'w'], 2 => ['file', '/dev/null', 'w']];
$server = proc_open(['php', '-S', '127.0.0.1:8208', 'api.php'], $quiet, $pipes);
usleep(300_000); // let the server start listening
$ctx = stream_context_create(['http' => ['method' => 'POST', 'timeout' => 5,
'header' => 'Content-Type: application/json', 'content' => '{"sku":"BK-101","qty":2}',
'ignore_errors' => true]]); // keep the body on 4xx and 5xx
echo file_get_contents('http://127.0.0.1:8208/orders', false, $ctx), ' ',
http_get_last_response_headers()[0], "\n";
var_dump(file_get_contents('http://127.0.0.1:8208/orders')); // a plain GET
proc_terminate($server);
file_put_contents('note.txt', "Ship order 5001\n");
echo file_get_contents('php://filter/read=string.toupper|string.rot13/resource=note.txt');{"type":"application\/json","body":{"sku":"BK-101","qty":2}} HTTP/1.1 201 Created
PHP Warning: file_get_contents(http://127.0.0.1:8208/orders): Failed to open stream: HTTP
request failed! HTTP/1.1 405 Method Not Allowed
in /home/dev/shop/main.php on line 11
bool(false)
FUVC BEQRE 5001Without ignore_errors, a 4xx or 5xx returns false and loses the error body. http_get_last_response_headers() (PHP 8.4) replaces $http_response_header, deprecated in PHP 8.5. A filter transforms bytes in transit: php://filter chains them onto a whole-file call, stream_filter_append() attaches one to a handle, and stream_get_filters() lists them. Keep allow_url_include off, use cURL or Guzzle 23,452 for real APIs (Making HTTP Requests with cURL-Guzzle, PSR-7 and PSR-18), and never fetch a user-chosen URL without an allow-list.