Question

PHP cURL HTTP POST Example: Sending Form Data and Reading the Response

phphttpcurlhttp-post

Question

How can I send an HTTP POST request in PHP using cURL?

I want to send form-style data like this:

  • username=user1
  • password=passuser1
  • gender=1

The request should be sent to www.example.com, and I expect the server to return a response such as result=OK.

What is a simple PHP cURL example that shows how to send this data and read the response?

Short Answer

By the end of this page, you will understand how to use PHP cURL to send an HTTP POST request, attach form data, receive the response, and handle common mistakes such as forgetting CURLOPT_RETURNTRANSFER or posting data in the wrong format.

Concept

In PHP, cURL is a library used to make HTTP requests from your code. It is commonly used to talk to APIs, submit forms programmatically, send login data, upload files, or communicate with other web services.

An HTTP POST request sends data to a server in the request body. This is different from a GET request, which usually sends data in the URL.

When you use cURL in PHP for a POST request, you usually do these things:

  1. Initialize a cURL session.
  2. Set the target URL.
  3. Tell cURL to use the POST method.
  4. Attach the data you want to send.
  5. Ask cURL to return the response as a string.
  6. Execute the request.
  7. Close the cURL session.

This matters in real programming because many systems require server-to-server communication. For example:

  • submitting payment details to a gateway
  • logging in to an external service
  • sending form data to an API
  • posting JSON or form fields to another application

For your example, the data looks like standard form fields, so the most common format is application/x-www-form-urlencoded, which is what regular HTML forms use by default.

Mental Model

Think of a cURL POST request like mailing a form to an office.

  • The URL is the office address.
  • The POST method means you are sending information inside the envelope.
  • The POST fields are the form values you put in the envelope.
  • The response is the letter the office sends back.

In PHP, cURL is the mail carrier. You tell it where to go, what method to use, what data to carry, and whether you want the reply handed back to your code.

Take Quiz

Syntax and Examples

The basic PHP cURL POST pattern looks like this:

<?php
$url = 'https://www.example.com';

$data = [
    'username' => 'user1',
    'password' => 'passuser1',
    'gender' => '1'
];

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);

if ($response === false) {
    echo 'cURL error: ' . curl_error($ch);
} else {
    echo $response;
}

curl_close($ch);

What this code does

  • curl_init($url) creates a cURL session for the target URL.
  • CURLOPT_POST tells cURL to send a POST request.
  • CURLOPT_POSTFIELDS attaches the data being sent.
  • http_build_query($data) converts the PHP array into this format:
    • username=user1&password=passuser1&gender=1
  • CURLOPT_RETURNTRANSFER makes cURL return the response as a string instead of printing it directly.
  • curl_exec($ch) sends the request.
  • curl_error($ch) helps debug failures.
  • curl_close($ch) frees resources.

A slightly more explicit version with headers

<?php
$url = 'https://www.example.com';

$data = [
    'username' => 'user1',
    'password' => 'passuser1',
    'gender' => '1'
];

$postData = http_build_query($data);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/x-www-form-urlencoded'
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($response === false) {
    echo 'Request failed: ' . curl_error($ch);
} else {
    echo "HTTP Status: $httpCode\n";
    echo "Response: $response";
}

curl_close($ch);

This version is useful when you want to inspect the HTTP status code too.

Step by Step Execution

Consider this example:

<?php
$data = [
    'username' => 'user1',
    'password' => 'passuser1',
    'gender' => '1'
];

$ch = curl_init('https://www.example.com');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

echo $response;

Step by step

  1. PHP creates an array named $data.

    • It contains three fields: username, password, and gender.
  2. curl_init('https://www.example.com') starts a cURL session.

    • The request is prepared for that URL.
  3. CURLOPT_POST is set to true.

    • This changes the HTTP method from the default GET to POST.
  4. CURLOPT_POSTFIELDS is set.

    • http_build_query($data) turns the array into: username=user1&password=passuser1&gender=1
    • That string becomes the request body.
  5. CURLOPT_RETURNTRANSFER is set to true.

    • Without this, the response may be output directly instead of being stored in $response.
  6. curl_exec($ch) sends the request to the server.

    • The server receives the POST data.
    • The server processes it.
    • The server sends a response back, such as result=OK.
  7. The response is stored in $response.

  8. curl_close($ch) ends the cURL session.

  9. echo $response prints the returned server response.

If the server returns result=OK, that exact text will be shown.

Real World Use Cases

PHP cURL POST requests are used in many practical situations:

  • Submitting login credentials

    • Send a username and password to an authentication endpoint.
  • Calling third-party APIs

    • Send search parameters, order details, or customer data to another service.
  • Webhook delivery

    • Post event data from your application to another system.
  • Payment and billing integrations

    • Send checkout or transaction data securely to a payment provider.
  • Internal microservice communication

    • One backend service sends data to another backend service.
  • Form automation

    • Simulate a form submission without a browser.

Example scenario:

<?php
$data = [
    'email' => 'customer@example.com',
    'plan' => 'pro'
];

This kind of data might be posted to a subscription API when a user upgrades their account.

Take Quiz

Real Codebase Usage

In real projects, developers usually wrap cURL logic in reusable functions or service classes instead of writing raw cURL code everywhere.

Common patterns

  • Validation before sending

    • Check required fields before making the request.
  • Guard clauses

    • Return early if important data is missing.
  • Error handling

    • Handle cURL errors and bad HTTP status codes separately.
  • Configuration-driven URLs

    • Store API base URLs in config files or environment variables.
  • Response parsing

    • Convert JSON responses into arrays with json_decode().
  • Timeouts

    • Prevent requests from hanging too long.

Example helper function

<?php
function postForm(string $url, array $data): array
{
    if (empty($url)) {
        return ['success' => false, 'error' => 'Missing URL'];
    }

    $ch = curl_init($url);

    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);

    $response = curl_exec($ch);
    $error = curl_error($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    curl_close($ch);

    if ($response === false) {
        return ['success' => false, 'error' => $error];
    }

    if ($httpCode >= 400) {
        return ['success' => false, 'error' => 'HTTP error ' . $httpCode, 'response' => $response];
    }

    return ['success' => true, 'response' => $response];
}

This pattern makes your code easier to test, reuse, and maintain.

Common Mistakes

Here are some common beginner mistakes when using PHP cURL for POST requests.

1. Forgetting CURLOPT_RETURNTRANSFER

Broken code:

<?php
$ch = curl_init('https://www.example.com');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'username=user1');
$response = curl_exec($ch);

Problem:

  • The response may be printed directly instead of stored properly.
  • $response may be true instead of the actual response body.

Fix:

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

2. Sending an array when the server expects URL-encoded form data

Sometimes this works, but not always in the format you expect.

Safer approach:

curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));

This creates standard form encoding.

3. Not checking for errors

Broken code:

<?php
$response = curl_exec($ch);
echo $response;

Problem:

  • If the request fails, you do not know why.

Fix:

if ($response === false) {
    echo curl_error($ch);
}

4. Missing the URL scheme

Risky:

$url = 'www.example.com';

Better:

$url = 'https://www.example.com';

Always include http:// or https://.

5. Forgetting to close the handle

Not closing cURL is small in short scripts, but bad practice in larger applications.

curl_close($ch);

6. Confusing POST body formats

A server might expect:

  • form data: application/x-www-form-urlencoded
  • JSON: application/json

If the API expects JSON, this is different from your current example.

<?php
$json = json_encode($data);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($json)
]);

Make sure the format matches what the server expects.

Comparisons

Here is a quick comparison of related request formats and options.

ConceptWhat it doesBest forExample
GETSends data in the URLReading dataexample.com?username=user1
POSTSends data in the request bodySubmitting datalogin forms, API writes
application/x-www-form-urlencodedStandard form encodingSimple form fieldsusername=user1&gender=1
application/jsonSends JSON textModern APIs{"username":"user1"}
CURLOPT_POSTForces POST methodStandard POST requestscurl_setopt($ch, CURLOPT_POST, true);
CURLOPT_POSTFIELDSSends request body dataForm fields or JSONrequest payload
CURLOPT_RETURNTRANSFERReturns response as a stringMost PHP scriptsstore result in a variable

Array vs http_build_query()

ApproachResultWhen to use
Pass raw array to CURLOPT_POSTFIELDSMay be encoded differently, sometimes multipartUseful in some cases, especially file uploads
Use http_build_query($data)Sends URL-encoded form dataBest for simple form posts like your example

For simple username/password/gender values, http_build_query() is usually the clearest choice.

Take Quiz

Cheat Sheet

<?php
$data = [
    'username' => 'user1',
    'password' => 'passuser1',
    'gender' => '1'
];

$ch = curl_init('https://www.example.com');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);

if ($response === false) {
    echo curl_error($ch);
} else {
    echo $response;
}

curl_close($ch);

Quick rules

  • Use curl_init() to start.
  • Use CURLOPT_POST for POST requests.
  • Use CURLOPT_POSTFIELDS to send data.
  • Use http_build_query() for standard form fields.
  • Use CURLOPT_RETURNTRANSFER to capture the response.
  • Check curl_exec() for false.
  • Use curl_error() for debugging.
  • Use curl_close() when finished.
  • Include https:// in the URL.

Useful extras

curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

If the API expects JSON instead

$json = json_encode($data);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);

FAQ

How do I send POST data with PHP cURL?

Use CURLOPT_POST to enable POST and CURLOPT_POSTFIELDS to send the data.

How do I get the response body instead of printing it directly?

Set CURLOPT_RETURNTRANSFER to true. Then curl_exec() returns the response as a string.

Should I pass an array or use http_build_query()?

For simple form fields, http_build_query() is usually the safest and clearest choice.

How do I know whether the request failed?

Check whether curl_exec() returns false, then read the error with curl_error($ch).

Can I send JSON instead of form data?

Yes. Use json_encode() and set the Content-Type: application/json header.

Why is my server not receiving the posted values?

Common causes include using the wrong content type, forgetting http_build_query(), using the wrong URL, or sending to an endpoint that expects a different format.

How can I see the HTTP status code?

Use:

$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

Do I need to close the cURL handle?

Yes. Call curl_close($ch) after the request to release resources.

Take Quiz

Mini Project

Description

Build a small PHP script that submits a mock registration form to a remote endpoint using cURL. This project demonstrates how to collect form-style values in an array, encode them properly, send them with an HTTP POST request, and inspect the response and status code.

Goal

Create a reusable PHP script that sends form data with cURL and prints either a clear error message or the server response.

Requirements

  1. Create a PHP array with at least username, password, and gender.
  2. Send the data to a URL using an HTTP POST request.
  3. Encode the data as standard form data.
  4. Return and display the response body.
  5. Display a useful error message if the request fails.
Take Quiz

Keep learning

Related questions

View more