convert python request to PHP-cURL equivalent
I am sending a POST request to a URL. It works correctly in python but in php-curl, I always get a bad request error (i.e. my POST data is not as expected by the server)
Python code: (works correctly. 200 OK)
import httplib, urllib, json
def SendRequest(param1):
url = "api.xyz.com"
body = {"version": "1.0", "data":[{"param1":param1, "age":35}]}
jsonBody = json.dumps(body)
headers = {"Content-type": "application/json",
"Accept": "application/json; charset=utf8"}
conn = httplib.HTTPConnection(url)
conn.request("POST", "/api/?client_id=xx-xx-xx", jsonBody, headers)
response = conn.getresponse()
php-cURL code (does not work. 406 Bad request error)
function sendCurlRequest($param1)
{
$payload = preparePayload($param1);
$url = "http://api.xyz.com/api/?client_id=xx-xx-xx";
$jsonResponse = executePOSTRequest($url, $payload);
$response = json_decode($jsonResponse);
}
function preparePayload($param1)
{
$payload = array("version" = "1.0",
"data" => array(array("param1" => $param1,
"age" => 35
)
),
);
$jsonPayload = json_encode($payload);
return $jsonPayload;
}
function executePOSTRequest($url, $payload)
{
$newlines = array("\r", "\n", " ");
$url = str_replace($newlines, '', $url);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_HTTPHEADERS,array('Content-Type:application/json; Accept: application/json; charset=utf8'));
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
}
I know there is some mistake in my use of cURL. Please suggest.
Update: Use of do开发者_JAVA技巧uble array in php is because server expects the JSON string (POST payload) in this format
{
"version": "1.0",
"data":
[{"param1":name, "age":35},{"param1":name,"age":60}]
}
In python, I am using list of dict; in php I think it is array of arrays only.
In a case like this, I find that it's always better to look at what goes over the wire instead of trying to puzzle out what might be wrong with the code.
My advice:
Create a little test server using the python
BaseHTTPServer
and derive a class fromBaseHTTPRequestHandler
that doesn't do anything but provide an override of thedo_POST
methodYour
do_POST
should just dump the headers and POST body it receives to filePoint your code samples at this little test server and then diff the files that it creates. I'm guessing that if the answer isn't immediately obvious, you'll at the very least get one or more useful clues to stomp this problem out.
I'm not sure if it causes your problem, but I do see a difference between the two: In the python code you send two header lines: Content-Type and Accept. While in the PHP code, they are a single line.
You are missing the parameter index - cURL POST fields need to be sent as a query string or as an array.
Either:
curl_setopt($ch, CURLOPT_POSTFIELDS, 'payload=' . urlencode($payload));
Or
curl_setopt($ch, CURLOPT_POSTFIELDS, array('payload' => $payload));
Replace payload
with the name of the parameter expected by the API to hold the JSON string.
If the endpoint API is not expecting a parameter, then it should work - it just won't appear in the POST array in your test script. You can fetch the body of the POST contents using
$data = file_get_contents("php://input");
var_dump($data);
精彩评论