4

the scope of my project is to pass certain values from a python script to a remote php script.

i've a python script that generate an associatve array. For example (already JSON encoded):

{"FRONT": "19.50", "RACK": "17.63", "REAR": "21.06", "ROOM": "15.6"}

I need to pass this associative array to a remote PHP script i followed this tutorial: http://nonstopblah.wordpress.com/2010/07/13/python-to-php-via-json/

I get 200 for HTTP Response but in the php script the POST variable seems to be empty

Here my code:

bulkData = json.dumps(temp, ensure_ascii = 'False')
# ensure_ascii is false as data is in unicode and not ascii encoding , use this if data is in any other encoding
print bulkData

print '\nHTTP Response'

headers = { "charset":"utf-8",
"Accept": "text/plain"}
conn = httplib.HTTPConnection(report_host)
postData = urllib.urlencode({'results':bulkData})
conn.request("POST", report_path, postData,headers)
response = conn.getresponse()
text = response.read()
print "Response status: ",response.status,"\n",text
conn.close()

this is the PHP script:

if( isset($_POST['results']) )
{
    $data = json_decode($_POST['results']);

    print_r($data);
}
else
{
    echo 'Nothing to listen.';
    print_r($_POST);
}

and this is the output of my python script (with the remote response):

{"FRONT": "20.44", "RACK": "18.88", "REAR": "21.25", "ROOM": "17.7"}

HTTP Response
Response status:  200 
Nothing to listen.Array
(
)

is there a smarter way to do it? What am i missing here?

Thank you in advance for your kind answers.

5
  • 1
    Have you tried logging the Content-Type received by the PHP script? You're sending "application/x-www-form-urlencoded" data, and if that arrives as, say, "text/plain", it may not work. (But really, why are you URL-encoding the data in the first place? Why not just send "application/json" and send the JSON as-is as the POST data?) Commented Nov 7, 2012 at 8:36
  • PS, Why are you writing the front-end and the back-end in different languages, neither of which you know very well, in the first place? It means there's twice as much to learn, and twice as much that can go wrong mysteriously. Why not just write the service in Python too (or, if you really must, write the client in PHP)? Commented Nov 7, 2012 at 9:03
  • PPS, looking over the blog post you linked, it seems like the author doesn't understand web services any better than you, so I'd recommend looking for a better tutorial. Commented Nov 7, 2012 at 9:04
  • @abarnert I'm quite familiar with PHP (the listener was just a test :) ) but not so much with python. I'd say you're generally right and that match language is a good idea but in this case it's not. The python script reads the data from a temperature probe in XML (it's a scheduled task) then post it back to a php script? Why this can't be done directly from the php script? Because this one is on a remote server outside the infrastructure, and no cannot be brought inside. PS. And before you ask SNMP (Security is not my problem :P) is not an option Commented Nov 7, 2012 at 9:16
  • If you know PHP a lot better… can you write a command-line PHP script instead of Python, or does the remote machine not have command-line PHP installed? Commented Jan 2, 2013 at 19:02

2 Answers 2

4

I'd skip the urlencoded form data. Just send the raw data in the body:

conn.request("POST", report_path, bulkData,headers)

Then you can read the request body in PHP with:

<?
$data = json_decode(file_get_contents('php://input'));
?>

The bulkData string is going to arrive as is in your php script.

Sign up to request clarification or add additional context in comments.

4 Comments

Okey this works! But how to put it into a post variable like for example: $_POST['results'] ?
@eldblz Why do you want to put it into $_POST['results']? Just say $results = file_get_contents('php://input');
Yes, as abarnert says, you don't need $_POST. This variable is just a convenience when the post content-type is url-encoded form data. With my solution the post content-type is directly the data.
Yes this is what i'm doing thanks and i've added "Content-type": "application/json"
0

I tested this locally with a dead-simple PHP CGI, and it only took a few seconds of debugging to figure out the problem:

You're sending URL-encoded data, but you're not setting the Content-Type appropriately. At least with apache2 as it comes configured on OS X 10.7, this means the CGI sees the data as just one big string, not a bunch of variables. And obviously, that string doesn't have a 'results' member.

Adding 'Content-Type': 'application/x-www-form-urlencoded' to your headers solves the problem. Alternatively, you can configure your web server to infer a default content type for POSTs to, say, /cgi-bin/*, which has the same net effect.

However, the real question is why you're both JSON-encoding and URL-encoding the data in the first place. They both do similar things. Since your temp object is just a dict with strings for all keys and values, you can just URL-encode that, and don't bother with JSON. Or, alternatively, just take the JSON-encoded bulkData and send that as-is as the POST data (ideally with 'Content-Type': 'application/json', although since you're explicitly going to be reading the data and calling json_decode on it, this isn't strictly necessary).

1 Comment

Do you by chance have a working example of this? I am having a similar problem myself: stackoverflow.com/questions/14109461/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.