HTTP Client
Introductionβ
The BowPHP HTTP client is a powerful and flexible component for making HTTP requests to APIs or remote services. It uses the cURL library to provide advanced features while keeping them simple to use.
Key featuresβ
- Supported HTTP methods:
GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS. - Custom header management.
- Support for attached files in multipart/form-data requests.
- Native JSON encoding of data.
- Definition of a base URL (
base_url) to simplify managing API endpoints. - Built-in authentication (Basic, Bearer, HTTP Auth).
- Timeout configuration and SSL verification.
- Error handling with specific exceptions.
Usageβ
To use the HTTP client, simply create a new instance or inject it into a service or controller:
use Bow\Http\Client\HttpClient;
$client = new HttpClient();
The constructor accepts an optional $base_url parameter. If the base URL is set, calling endpoints becomes simpler:
$client = new HttpClient('https://api.example.com');
If you did not set the base URL when creating the instance, use setBaseUrl to do it later:
$client->setBaseUrl('https://api.example.com');
HTTP methodsβ
getβ
Performs a GET request to retrieve resources.
Parameters:
$url: The relative path or full URL$data: Array of parameters appended to the URL as a query string
Returns: A Response instance
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client->get('/users', ['page' => 2, 'limit' => 10]);
echo $response->getContent();
// Access the JSON data
$users = $response->toArray();
postβ
Performs a POST request to create or send data.
Parameters:
$url: The relative path or full URL$data: Array of data to send (JSON or form-urlencoded depending on the configuration)
Returns: A Response instance
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client->acceptJson()->post('/users', [
'name' => 'John Doe',
'email' => 'john.doe@example.com',
'role' => 'admin'
]);
// Check for success
if ($response->isSuccessful()) {
$user = $response->toArray();
echo "User created with ID: {$user['id']}";
}
putβ
Performs a PUT request to update an existing resource.
Parameters:
$url: The relative path or full URL$data: Array of data to send for the update
Returns: A Response instance
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client->acceptJson()->put('/users/123', [
'name' => 'Jane Doe',
'email' => 'jane.doe@example.com'
]);
if ($response->isSuccessful()) {
echo "User updated successfully";
}
deleteβ
Performs a DELETE request to remove a resource.
Parameters:
$url: The relative path or full URL$data: Array of optional data to send
Returns: A Response instance
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client->delete('/users/123');
if ($response->isSuccessful()) {
echo "User deleted successfully";
}
patchβ
Performs a PATCH request to partially update a resource.
Parameters:
$url: The relative path or full URL$data: Array of data to send for the partial update
Returns: A Response instance
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client->acceptJson()->patch('/users/123', [
'email' => 'newemail@example.com'
]);
if ($response->isSuccessful()) {
echo "Email updated successfully";
}
headβ
Performs a HEAD request to retrieve only the HTTP headers, without the response body. Useful for checking whether a resource exists or obtaining metadata.
Parameters:
$url: The relative path or full URL$data: Array of parameters appended to the URL as a query string
Returns: A Response instance
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client->head('/large-file.zip');
if ($response->isSuccessful()) {
$headers = $response->getHeaders();
echo "File size: " . ($headers['download_content_length'] ?? 'unknown');
}
optionsβ
Performs an OPTIONS request to discover the HTTP methods allowed on a resource. Often used for CORS preflight requests.
Parameters:
$url: The relative path or full URL
Returns: A Response instance
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client->options('/users');
// The allowed methods are usually in the Allow header
$headers = $response->getHeaders();
Advanced configurationβ
addAttachβ
Attaches one or more files to a multipart/form-data request.
Parameters:
$attach: File path (string) or array of file paths
Returns: The client instance for fluent chaining
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
// Upload a single file
$response = $client->addAttach('/path/to/document.pdf')
->post('/upload');
// Upload multiple files
$response = $client->addAttach([
'/path/to/image1.jpg',
'/path/to/image2.jpg'
])->post('/upload-multiple');
withHeadersβ
Adds custom HTTP headers to the request.
Parameters:
$headers: Associative array of headers
Returns: The client instance for fluent chaining
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client
->withHeaders([
'Authorization' => 'Bearer your-api-token',
'X-Custom-Header' => 'custom-value'
])
->get('/protected-endpoint');
echo $response->getContent();
setUserAgentβ
Sets the User-Agent for the request.
Parameters:
$user_agent: String representing the user agent
Returns: The client instance for fluent chaining
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client
->setUserAgent('MyApp/1.0 (BowPHP)')
->get('/users');
echo $response->getContent();
acceptJsonβ
Configures the client to send and accept data in JSON format.
Automatically adds the Content-Type: application/json and
Accept: application/json headers.
Returns: The client instance for fluent chaining
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client
->acceptJson()
->post('/users', [
'name' => 'John Doe',
'email' => 'john@example.com'
]);
// The data will be automatically encoded as JSON
$result = $response->toArray();
withJsonβ
Configures the client to send data in JSON format, without enforcing
the response format. Only adds the Content-Type: application/json header.
Use withJson when the remote API accepts JSON as input but
returns another format (XML, HTML, plain text). Use acceptJson when
the exchange is JSON in both directions.
Returns: The client instance for fluent chaining
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client
->withJson()
->post('/webhook', ['event' => 'order.created', 'order_id' => 42]);
hasHeaderβ
Checks whether a specific header (key and value) has already been added to the request. Handy for avoiding adding the same conditional header twice.
Parameters:
$key: Header name$value: Expected value
Returns: bool
Example:
$client = new HttpClient('https://api.example.com');
$client->withHeaders(['X-Trace-Id' => 'abc-123']);
if (!$client->hasHeader('X-Trace-Id', 'abc-123')) {
$client->withHeaders(['X-Trace-Id' => 'abc-123']);
}
Authenticationβ
basicAuthβ
Configures HTTP Basic authentication with Base64 encoding of the credentials.
Parameters:
$key: Key or username$secret: Secret or password
Returns: The client instance for fluent chaining
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client
->basicAuth('api_key', 'api_secret')
->get('/protected-resource');
bearerAuthβ
Configures Bearer token authentication (OAuth2, JWT, etc.).
Parameters:
$token: The authentication token
Returns: The client instance for fluent chaining
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client
->bearerAuth('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...')
->get('/user/profile');
authβ
Configures cURL's native HTTP authentication.
Parameters:
$username: Username$password: Password
Returns: The client instance for fluent chaining
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client
->auth('username', 'password')
->get('/protected');
Timeouts and SSLβ
timeoutβ
Sets the maximum time allowed for the complete execution of the request.
Parameters:
$seconds: Duration in seconds
Returns: The client instance for fluent chaining
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client
->timeout(30) // 30 seconds maximum
->get('/slow-endpoint');
connectTimeoutβ
Sets the maximum time to establish the connection to the server.
Parameters:
$seconds: Duration in seconds
Returns: The client instance for fluent chaining
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://api.example.com');
$response = $client
->connectTimeout(5) // 5 seconds to establish the connection
->timeout(30)
->get('/endpoint');
disableSslVerificationβ
Disables SSL certificate verification. Warning: use only in a development environment.
Returns: The client instance for fluent chaining
Example:
use Bow\Http\Client\HttpClient;
$client = new HttpClient('https://localhost:8443');
$response = $client
->disableSslVerification()
->get('/api/test');
Never disable SSL verification in production. Doing so exposes your application to man-in-the-middle attacks.
Exception handlingβ
You must distinguish between two levels of error:
- Transport error β the request could not complete at all (connection
refused, host not found, timeout exceeded, SSL negotiation failure).
In this case, the client throws a
Bow\Http\Client\HttpClientExceptioncarrying the cURL error message and code. - HTTP error response β the request completed but the server responds with
an error status (
404,500, β¦). No exception is thrown: you get aResponseinstance and inspect its status viaisFailed()/getCode().
use Bow\Http\Client\HttpClient;
use Bow\Http\Client\HttpClientException;
$client = new HttpClient('https://api.example.com');
try {
$response = $client->acceptJson()->get('/users');
// The request completed: check the returned HTTP status
if ($response->isFailed()) {
// 4xx / 5xx β no exception, read the code
logger()->warning('API responded ' . $response->getCode());
return;
}
$users = $response->toArray();
} catch (HttpClientException $e) {
// Network / SSL / timeout failure: the request never completed
logger()->error('HTTP failure: ' . $e->getMessage(), ['code' => $e->getCode()]);
}
The client relies on the curl extension. If it is not loaded, instantiating
HttpClient throws a BadFunctionCallException.
The Response classβ
The Response class encapsulates all the information returned by an HTTP request: content, headers, status code, and performance metrics. It provides a simple and intuitive interface for working with responses.
Main methodsβ
getContentβ
public function getContent(): ?string
Returns the raw content of the HTTP response as a string. Returns null if no content is available.
Example:
$content = $response->getContent();
echo $content;
toJsonβ
public function toJson(?bool $associative = null): object|array
Decodes the JSON content of the response into a PHP object or array.
Parameters:
$associative:truefor an associative array,falsefor an object (default)
Example:
// Returns an object
$user = $response->toJson();
echo $user->name;
// Returns an array
$userData = $response->toJson(true);
echo $userData['name'];
toArrayβ
public function toArray(): array
Alias for toJson(true). Returns the JSON content as an associative array.
Example:
$users = $response->toArray();
foreach ($users as $user) {
echo $user['name'];
}
getHeadersβ
public function getHeaders(): array
Returns the metadata array produced by curl_getinfo() for the request.
This array is not the raw list of HTTP response headers: it
contains cURL keys such as http_code, content_type, total_time,
connect_time, size_upload, size_download, download_content_length, etc.
If you need a specific raw HTTP header (e.g. Location,
X-Request-Id), parse it via CURLOPT_HEADERFUNCTION or use the appropriate
cURL configuration option on the remote server side.
getCode / statusCodeβ
public function getCode(): ?int
public function statusCode(): ?int
Return the HTTP status code of the response (200, 404, 500, etc.). Returns null if unavailable.
Example:
$code = $response->getCode();
// or
$code = $response->statusCode();
if ($code === 200) {
echo "Request successful";
}
isSuccessfulβ
public function isSuccessful(): bool
Returns true if the status code indicates success (200 or 201).
Example:
if ($response->isSuccessful()) {
$data = $response->toArray();
// Process the data
}
isFailedβ
public function isFailed(): bool
Returns true if the request failed (status code other than 200 or 201).
Example:
if ($response->isFailed()) {
echo "Error: " . $response->getCode();
}
Performance metricsβ
The HTTP client provides several methods to analyze request performance:
| Method | Description | Return |
|---|---|---|
getExecutionTime() | Total request execution time (cURL key total_time) | mixed (usually ?float, seconds) |
getConnexionTime() | Connection establishment time | ?float (seconds) |
getUploadSize() | Size of the data sent | ?float (bytes) |
getUploadSpeed() | Upload speed | ?float (bytes/sec) |
getDownloadSize() | Size of the data received | ?float (bytes) |
getDownloadSpeed() | Download speed | ?float (bytes/sec) |
Example usage:
$response = $client->get('/large-data');
echo "Execution time: " . $response->getExecutionTime() . "s\n";
echo "Downloaded size: " . $response->getDownloadSize() . " bytes\n";
echo "Speed: " . $response->getDownloadSpeed() . " bytes/s\n";
Error handlingβ
getErrorMessage: Returns the cURL error message if there is one, otherwise an empty string.
getErrorNumber: Returns the cURL error code.
Example:
if ($response->isFailed()) {
echo "Error #{$response->getErrorNumber()}: {$response->getErrorMessage()}";
}
Other methodsβ
getContentTypeβ
public function getContentType(): ?string
Returns the MIME type of the content (e.g. application/json, text/html).
Example:
$contentType = $response->getContentType();
if ($contentType === 'application/json') {
$data = $response->toArray();
}
Is something missing?
If you run into problems with the documentation or have suggestions to improve the documentation or the project in general, please open an issue for us, or send a tweet mentioning the Twitter account @bowframework or directly on github.