PHP
POST Request
Web Development
Coding
Programming

How do I send a POST request with PHP?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Sending a POST request in PHP usually means making an HTTP request to another server or API and putting data in the request body. The most practical tool for this is cURL because it gives you control over headers, request body format, timeouts, and error handling.

Sending a JSON POST request with cURL

A common API pattern is JSON over HTTP. In PHP, the core steps are: encode the payload, set cURL options, execute the request, and inspect the response.

php
1<?php
2$url = 'https://httpbin.org/post';
3$payload = [
4    'name' => 'Ava',
5    'role' => 'admin',
6];
7
8$ch = curl_init($url);
9
10curl_setopt_array($ch, [
11    CURLOPT_POST => true,
12    CURLOPT_RETURNTRANSFER => true,
13    CURLOPT_HTTPHEADER => [
14        'Content-Type: application/json',
15    ],
16    CURLOPT_POSTFIELDS => json_encode($payload),
17    CURLOPT_TIMEOUT => 10,
18]);
19
20$response = curl_exec($ch);
21
22if ($response === false) {
23    throw new RuntimeException(curl_error($ch));
24}
25
26$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
27curl_close($ch);
28
29echo $statusCode . PHP_EOL;
30echo $response . PHP_EOL;

This is the pattern most developers reach for when calling REST APIs.

Sending form data instead of JSON

Not every server expects JSON. Some endpoints want regular form-encoded data:

php
1<?php
2$url = 'https://httpbin.org/post';
3$payload = [
4    'username' => 'demo',
5    'password' => 'secret',
6];
7
8$ch = curl_init($url);
9
10curl_setopt_array($ch, [
11    CURLOPT_POST => true,
12    CURLOPT_RETURNTRANSFER => true,
13    CURLOPT_HTTPHEADER => [
14        'Content-Type: application/x-www-form-urlencoded',
15    ],
16    CURLOPT_POSTFIELDS => http_build_query($payload),
17]);
18
19$response = curl_exec($ch);
20
21if ($response === false) {
22    throw new RuntimeException(curl_error($ch));
23}
24
25curl_close($ch);
26echo $response;

The difference is in the body format and the matching Content-Type header.

Reading the response safely

A POST request is not complete until you inspect the response properly. At minimum, check:

  • whether cURL execution failed,
  • the HTTP status code,
  • and whether the response body is valid JSON if the API promises JSON.
php
1<?php
2$data = json_decode($response, true);
3
4if ($statusCode !== 200) {
5    throw new RuntimeException('Unexpected HTTP status: ' . $statusCode);
6}
7
8if (!is_array($data)) {
9    throw new RuntimeException('Invalid JSON response');
10}

That prevents silent failures where the request technically completes but the remote server rejects the payload.

A simpler stream-context alternative

If cURL is unavailable, PHP can also send a POST request with stream contexts:

php
1<?php
2$options = [
3    'http' => [
4        'method' => 'POST',
5        'header' => "Content-Type: application/json\r\n",
6        'content' => json_encode(['ping' => 'pong']),
7        'timeout' => 10,
8    ],
9];
10
11$context = stream_context_create($options);
12$response = file_get_contents('https://httpbin.org/post', false, $context);
13
14echo $response;

This works for simple cases, but cURL is still the better default because it offers better diagnostics and more features.

Common Pitfalls

The most common mistake is sending JSON data without the Content-Type: application/json header. Many APIs will reject or misread the body if the header does not match the payload format.

Another issue is forgetting CURLOPT_RETURNTRANSFER. Without it, the response may be printed directly instead of being captured in your PHP variable.

Be careful with SSL and timeouts too. Disabling SSL verification to make a local test work is a bad habit, and omitting timeouts can leave the process hanging indefinitely.

Finally, do not assume every successful network call means a successful application result. An HTTP 400 or 500 response still means the request reached the server, so always inspect the status code. Logging both the request format and the response body during development can save a lot of time when an API rejects your payload for a schema mismatch.

Summary

  • Use cURL for most PHP POST requests.
  • Match the body format and the Content-Type header.
  • Capture the response and check for cURL errors and HTTP status codes.
  • Use http_build_query() for form data and json_encode() for JSON payloads.
  • Stream contexts work for simple cases, but cURL is usually more robust.

Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions