Free tools Windows power users keep installed
One-click scans. No signup required.
Use json_encode() to turn a PHP array into JSON, send that string as the POST body, and set Content-Type: application/json. In PHP, cURL gives the most explicit transport and error controls; the HTTP stream wrapper is a dependency-light alternative. If your PHP code receives the request, read JSON from php://input rather than expecting it in $_POST.
The request pattern
Every JSON POST has four independent parts: the destination URL, a JSON-encoded body, headers that describe the body, and response/error handling. The endpoint’s own documentation still determines authentication, required fields, and the response contract.
- Create a PHP array or object representing the payload.
- Encode it with
json_encode(). - Send the resulting string as the request body.
- Set
Content-Type: application/json; request JSON back withAccept: application/jsonwhen appropriate. - Check transport errors, the HTTP status, and the response body.
Send JSON with PHP cURL
Complete example
<?php
$data = [
'name' => 'Ada',
'active' => true,
];
try {
$json = json_encode($data, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
throw new RuntimeException('Could not encode request JSON: ' . $e->getMessage(), 0, $e);
}
$ch = curl_init('https://api.example.test/endpoint');
if ($ch === false) {
throw new RuntimeException('Could not initialize cURL');
}
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Accept: application/json',
],
]);
$response = curl_exec($ch);
if ($response === false) {
$error = curl_error($ch);
curl_close($ch);
throw new RuntimeException('cURL request failed: ' . $error);
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status < 200 || $status >= 300) {
throw new RuntimeException('API returned HTTP ' . $status . ': ' . $response);
}
echo $response;
This follows the PHP manual’s documented pattern: encode the array, pass the JSON text through CURLOPT_POSTFIELDS, declare the content type with CURLOPT_HTTPHEADER, and enable CURLOPT_RETURNTRANSFER so the response is returned as a string. The example also makes encoding failures and non-success HTTP responses visible to the caller. Ensure the cURL extension and the JSON exception syntax used by your project are available in the target PHP runtime.
Authentication and additional headers
Add the exact authentication header required by the API. For example, a bearer-token API commonly documents an Authorization header; do not assume a scheme or header name that the endpoint has not specified. Keep secrets outside source control and do not log them with the request body.
#1 Best Overall
$headers = [
'Content-Type: application/json',
'Accept: application/json',
'Authorization: Bearer ' . $token,
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
Likewise, include an API-specific idempotency, correlation, or version header only when that API documents it. Headers do not replace a correctly shaped JSON payload.
Send JSON with the HTTP stream wrapper
Complete example
<?php
$data = [
'name' => 'Ada',
'active' => true,
];
$json = json_encode($data, JSON_THROW_ON_ERROR);
$options = [
'http' => [
'method' => 'POST',
'header' => [
'Content-Type: application/json',
'Accept: application/json',
],
'content' => $json,
],
];
$context = stream_context_create($options);
$response = file_get_contents(
'https://api.example.test/endpoint',
false,
$context
);
if ($response === false) {
throw new RuntimeException('The HTTP stream request failed');
}
echo $response;
The HTTP context accepts a method, header lines, and body content. Headers can be supplied as an array of lines, as shown, or as one string with lines separated by rn. Check the return value and inspect response metadata when your application needs the HTTP status or headers. The endpoint’s authentication and payload rules remain the same as with cURL.
When streams are a good fit
Use this approach when the PHP stream wrapper is enabled and you want a small implementation without cURL-specific options. Confirm that the relevant wrapper and context options suit your deployment. The PHP manual notes version-specific changes to stream-context options, so verify behavior against the runtime you deploy.
Rank #2
How a PHP endpoint receives JSON
Read the raw body
<?php
$rawBody = file_get_contents('php://input');
$data = json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR);
$name = $data['name'] ?? null;
$active = $data['active'] ?? false;
For application/json, PHP does not populate $_POST the way it does for application/x-www-form-urlencoded and multipart/form-data. Read the raw request body from php://input, then decode it. The receiver should validate that the decoded value has the expected type and required fields before using it.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Handle malformed or empty input
<?php
$rawBody = file_get_contents('php://input');
if ($rawBody === false || trim($rawBody) === '') {
http_response_code(400);
header('Content-Type: application/json');
echo json_encode(['error' => 'Request body is required']);
exit;
}
try {
$data = json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
http_response_code(400);
header('Content-Type: application/json');
echo json_encode(['error' => 'Malformed JSON']);
exit;
}
if (!is_array($data) || !array_key_exists('name', $data)) {
http_response_code(422);
header('Content-Type: application/json');
echo json_encode(['error' => 'The name field is required']);
exit;
}
Choose the response status and error format required by your API contract. Parsing JSON successfully does not mean the payload is valid for the application.
Encoding payloads correctly
Use JSON types, not a query string
Pass the JSON text directly as the body. Do not run a JSON payload through http_build_query(); that produces form-style key/value encoding, not JSON. PHP arrays become JSON objects or arrays according to their keys, booleans remain JSON booleans, and null becomes JSON null.
$payload = [
'customer' => [
'id' => 123,
'tags' => ['trial', 'newsletter'],
],
'sendReceipt' => false,
'note' => null,
];
$json = json_encode($payload, JSON_THROW_ON_ERROR);
Check character encoding
All string data passed to json_encode() must be UTF-8. An encoding failure returns false unless you use an error-throwing flag such as JSON_THROW_ON_ERROR. Treat that failure as a local input problem and fix or normalize the source string before making the HTTP request.
Do not confuse transport success with API success
A completed TCP/HTTP exchange only proves that a response arrived. Always inspect the status code and response body for authentication failures, schema errors, rate limits, or other endpoint-specific outcomes. A successful response may itself contain JSON that should be decoded and validated.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →cURL or streams?
| Consideration | cURL | HTTP stream context |
|---|---|---|
| Request construction | Set cURL options for the method, body, and headers. | Set http context options for method, headers, and content. |
| Response handling | CURLOPT_RETURNTRANSFER returns the body; cURL errors can be read with curl_error(). |
Use the stream function’s return value and inspect response metadata as needed. |
| Deployment fit | Requires the cURL extension to be available. | Uses PHP stream functionality; confirm the wrapper and options are suitable. |
| API requirements | Both still require the endpoint’s URL, authentication, payload schema, and response handling. | |
There is no universal performance winner established by the PHP manual material. Pick cURL when you need its explicit transfer controls and diagnostics; pick streams when the wrapper is available and the simpler context API fits your application.
Rank #4
Troubleshooting JSON POST requests
The server says the body is empty
- Confirm that
CURLOPT_POSTFIELDSor the stream context’scontentcontains the JSON string, not the original PHP array. - Confirm that the request uses
Content-Type: application/json. - On a PHP receiver, read
php://input; do not rely on$_POSTfor JSON.
$_POST is empty
This is expected for a JSON content type. Read and decode php://input as shown above. $_POST is intended for form-encoded and multipart form bodies.
json_encode() fails
- Check the exception message when using
JSON_THROW_ON_ERROR, or test explicitly for afalsereturn when not using that flag. - Find non-UTF-8 strings in the payload and convert or reject them before encoding.
- Verify that values are representable in the JSON structure your endpoint expects.
The request cannot connect
- Verify the URL and that the endpoint accepts
POST. - For cURL, capture and log
curl_error()without exposing credentials. - For streams, check whether
file_get_contents()returnedfalseand inspect available response metadata. - Confirm that the deployment permits outbound HTTPS and that the required PHP extension or stream wrapper is enabled.
The API returns an error status
Read the response body before changing the PHP transport code. Authentication, required fields, content limits, and validation rules are endpoint-specific. Compare the exact JSON shape and headers with that API’s documentation.
The response is not valid JSON
Do not blindly call json_decode() on every response. First check the HTTP status and the response’s content type or documented contract. Some endpoints return an empty body or plain text for errors.
Operational safeguards
- Keep the endpoint URL, credentials, and environment-specific headers configurable.
- Log status codes and a safely redacted request identifier, not authorization headers or sensitive JSON fields.
- Set limits and retry behavior according to the target API’s documentation rather than applying a generic policy.
- Validate decoded responses before using them in database writes, redirects, or other side effects.
- Test malformed JSON, missing fields, non-UTF-8 input, transport failure, and non-2xx responses.
Or skip the browser setup
If your PHP workflow also needs a clean screenshot of a URL, ScreenshotNeo provides a single HTTP call instead of maintaining browser automation. It accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.
curl -G 'https://api.screenshotneo.com/v1/shot'
-d access_key=YOUR_API_KEY
--data-urlencode url=https://itechguides.com
-o shot.webp
See the ScreenshotNeo documentation for the 63 capture options, including full-page and element shots, device and retina settings, PDF output, custom CSS and JavaScript, click and wait actions, request blocking, headers, cookies, geolocation, caching, signed links, asynchronous webhooks, bulk capture, and the usage API. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
The Free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 shots; every feature is included on every plan. Create a free ScreenshotNeo account to get an API key.
Frequently Asked Questions
Should I send a PHP array or a JSON string to CURLOPT_POSTFIELDS?
Send the string returned by json_encode(). Passing an array can select a different encoding behavior and will not guarantee an application/json request.
Can I use file_get_contents() for authenticated JSON APIs?
Yes, when the HTTP stream wrapper is available. Add the authentication header required by the API to the context’s header list and handle a false return plus response metadata.
Does setting Accept: application/json force the server to return JSON?
No. Accept expresses what your client prefers; the endpoint decides whether it supports that representation and what it returns.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

