I am using stream_socket_client() on my development server (linux box, PHP 5.2) to pull data asynchronously and it works flawlessly. I pull the same code down to my local windows laptop, running a local WAMP (PHP 5.4) stack and my code out errors out saying the connection is closed when I try to fwrite() the header to the connection. Removing the STREAM_CLIENT_ASYNC_CONNECT parameter from the stream_socket_client line allows the header to be sent. My question is whether anyone knows if there is a problem with stream_socket_client() either with Windows or with PHP version 5.4?
This has me really scratching my head.
Sample Code:
function get_api_data($url, $format = "json", $debug = 0) {
// Explode out the parameters.
$url_array = explode("/", $url);
// Is it http or https?
$method = strtolower(array_shift($url_array));
// Pop off an array blank.
array_shift($url_array);
// Get the host.
$host = array_shift($url_array);
// Get the rest of the url.
$get_params = "/" . implode("/", $url_array);
// Additional parameters.
$addr = gethostbyname($host);
$timeout = 60;
// Set up socket connection parameters.
switch ($method) {
case "http:":
$socket_type = "tcp://";
$port = ":80";
break;
case "https:":
$socket_type = "ssl://";
$port = ":443";
break;
default:
echo "Only HTTP and HTTPS protocols currently supported";
break;
}// End switch($method);
// Make an asynchronous data connection.
$fp = stream_socket_client($socket_type . $addr . $port, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT );
if ($debug == 1 && $fp) {
echo "<br />Connection to " . $socket_type . $addr . $port . " Achieved<br />";
}
if ($debug == 1 && !$fp) {
echo "<br />Connection to " . $socket_type . $addr . $port . " Not Achieved<br />";
}
// If the connection is made, send the request in the header:
if ($fp !== false) {
$headers = "GET $get_params HTTP/1.0\r\n";
$headers .= "Host: $host\r\n";
$headers .= "Accept: */*\r\n";
$headers .= "Content-type: application/$format; charset=utf8\r\n";
$headers .= "Connection: close\r\n\r\n";
if ($debug == 1) {
echo "<br />Headers to be sent are:<br ><pre>$headers</pre><br />";
}
/* lines below were added as an attempt to fix the issue. It didn't, so taking them out for now. */
//if(stream_set_blocking($fp, 0) === false) echo "<br />Cannot set Stream Blocking Mode<br />";
//else echo "<br />Stream Blocking Mode is set<br />";
if($fp !== false)$fwrite=fwrite($fp, $headers);
if($fwrite === false) echo "<br />Cannot write header<br />";
else echo "<br />Header written $fwrite bytes<br />";
// This line keeps the system from locking up...
stream_set_timeout($fp, 1);
// Now, retrieve the data.
$data = stream_get_contents($fp,-1);
// Close the connection.
fclose($fp);
} // End if($fp).
// If the format is json, the delimiter is "{", if xml, the delimiter is "<".
if ($format == "json") {
$delimiter = "{";
}
if ($format == "xml") {
$delimiter = "<";
}
// Strip out header information, leaving only the data.
$data_arr = explode($delimiter, $data);
$data_header = array_shift($data_arr);
$data = implode($delimiter, $data_arr);
if ($data != "") {
$data = $delimiter . $data;
}
$pubs_arr = array();
// Convert the xml format to an array.
if ($format == "xml") {
$pubs_arr = json_decode(json_encode((array) simplexml_load_string($data)), 1);
}
// Convert the JSON format to an array.
if ($format == "json") {
$pubs_arr = json_decode($data, TRUE);
}
// Append the data header into the array, for testing.
$pubs_arr['dataHeader'] = $data_header;
return ($pubs_arr);
}// End function get_api_data($url,$format="json",$debug=0).
Sample execution of the function:
$myDataArr = get_api_data("http://store.samhsa.gov/api/r/xml/websitelist?terms=Recovery","xml",1);
echo "<br /><pre>" . print_r($myDataArr) . "</pre><br />";
Error message I get is "Notice: fwrite(): send of 155 bytes failed with errno=10057 A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied", with a line reference that goes to line 60, where I write the headers, which is:
if($fp !== false)$fwrite=fwrite($fp, $headers);
Any ideas or thoughts would be very welcome...