Here's how I used curl and got the full response body on a 403 error. You trick it setting CURLOPT_FAILONERROR to false, so it doesn't fail on error (and hides the response body), and then check the response HTTP code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://example.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FAILONERROR, 0); // Do not fail on HTTP errors
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // follow redirects
curl_setopt($ch, CURLOPT_HEADER, 0); // Do not include header in output
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($response === false) {
echo 'Curl error: ' . curl_error($ch);
}
if($httpCode >= 400) {
// The request did not succeed, but we got a HTTP response
echo 'HTTP error: ' . $httpCode . ' with message: ' . $response;
} elseif($response !== false) {
// Success
echo 'Successful request: ' . $response;
}
curl_close($ch);