You can do it without curl in recentish versions (4.3.0 +).
Use the fopen context wrappers stuff; you can create posts with whatever payload you want.
Incidentially, data with content type "application/x-www-form-urlencoded" is not XML, so either you've got the content type wrong, or it isn't XML.
And yes, the COM Object XmlHttpRequest can be used to post non-XML data. It's badly named that's all.
What you need to do is create a stream context:
$context_options = array(
'http'=>array(
'method'=>"POST",
'header'=>"Accept-language: en\r\n" .
"Content-length: " . strlen($urlencoded) . "\r\n" .
"Content-type:application/x-www-form-urlencoded\r\n",
'content'=> $urlencoded)
);
// Make sure the HTTPS options are the same as HTTP
$context_options['https'] = $context_options['http'];
$context = stream_context_create($context_options);
$fp = fopen($url, 'r', false, $context);
As you can see, you create an associative array of context options, one of which is "content" which contains the POST payload. The others are also required.
Note that the above code does not post XML either, but rather a x-www-form-urlencoded POST, which is more common.
Mark