HTTP POST using PHP
When I first started using HTTP within code, I was using Perl, and doing things the old-fashioned way; hand-crafting requests and responses like this:
print qq|Content-type: text/html
Status: 303 See Other
Location: viewlog.pl?lognum=$lognum
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
...
Old code! XHTML 1.1! Oh the embarrassment!
Anyway, I’ve been pottering around in PHP, and I was looking for a nice way to submit a POST request over HTTPS, without using crazy external programs like curl, or opening sockets on port 81, and in my research I found a pile of info, which I have pieced together like this:
// Here are our form fields
$post_data = array(
'field1' => 'value1'
, 'field2' => 'value2'
);
// Build HTTP post query
$http_content = http_build_query($post_data);
$context_params = array(
'http' => array(
'method' => 'POST'
, 'content' => $http_content
)
);
$file_context = stream_context_create($context_params);
// Open file over HTTP
$file = file_get_contents('https://www.url.com', false, $file_context);
if (!$file) {
echo 'Error getting file!';
} else {
echo htmlspecialchars($file);
}
html_build_query() is PHP5-only, but all it’s really doing is gluing my parameters together with ampersands and equal signs.
stream_context_create() is a magical function which provide a resource object you can use to alter the behaviour of file handling functions like fopen() and file_get_contents(). We’re using it here to specify that this is a POST request.
What had me stuck for a while was the tricky second paramter in file_get_contents(). The PHP manual page currently defines the function like this:
string file_get_contents ( string $filename [, resource $context [, int $flags [, int $offset [, int $maxlen]]]] )
Which can’t be right, if I’m passing my context resource as the third parameter, can it? I only learnt to add the falseness after looking at some other examples. Not sure what I’m falsifying though…