I'm trying to send a request to a remote server using the fire-and-forget approach. This is my code:
function backgroundPost($url, $data = array()){
$parts=parse_url($url);
$fp = fsockopen($parts['host'],
isset($parts['port'])?$parts['port']:80,
$errno, $errstr, 30);
if (!$fp) {
return false;
} else {
$encoded_data = json_encode($data);
$output = "POST ".$parts['path']." HTTP/1.1\r\n";
$output .= "Host: ".$parts['host']."\r\n";
$output .= "Content-Type: application/json\r\n";
$output .= "Content-Length: " . strlen($encoded_data) . "\r\n";
$output .= "Connection: Close\r\n\r\n";
$output .= $encoded_data;
fwrite($fp, $output);
fclose($fp);
return true;
}
}
//Example of use
backgroundPost('url-here', array("foo" => "bar"));
but the data that arrives is simply empty.
When I spin up the application locally and send the request to my own machine instead, the data does arrive.
Am I misunderstanding something about this pattern?
Why is it working when sending a request to my own machine but not a remote one?
Thanks!
Related
I need to run a php code in a different server (let's call it server 2) from server 1.
In server 1, I have something like this
<?php
file_get_contents('http://domain_in_server_2.com/php-script.php');
?>
The problem is, this request may take long time, and I don't need to get the output. I just want to trigger the script without having to wait or getting the output.
Is there anyway to accomplish what I want?
Thank you very much.
You can use a socket. See this example.
Edit:
Here is the code from the above link:
// Example:
// post_async("http://www.server.com/somewhere",array("foo" => 123, "bar" => "ABC"));
function post_async($url, $params)
{
// Build POST string
foreach ($params as $key => &$val) {
if (is_array($val)) $val = implode(',', $val);
$post_params[] = $key.'='.urlencode($val);
}
$post_string = implode('&', $post_params);
// Connect to server
$parts=parse_url($url);
$fp = fsockopen($parts['host'],isset($parts['port'])?$parts['port']:80,$errno, $errstr, 30);
// Build HTTP query
$out = "$type ".$parts['path']." HTTP/1.1\r\n";
$out.= "Host: ".$parts['host']."\r\n";
$out.= "Content-Type: application/x-www-form-urlencoded\r\n";
$out.= "Content-Length: ".strlen($post_string)."\r\n";
$out.= "Connection: Close\r\n\r\n";
$out.= $post_string;
// Send data and close the connection
fwrite($fp, $out);
fclose($fp);
}
I would like to create a locally persistent connection with my site.
I would like to create a single connection where I can exchange infinite messages.
I used the code below.
but it's really persistent? inside the "while" open (fsockopen) and close (fclose) the connection, but if I take them out of the "while" gives me problems.
$url="localhost/socket/socket.php";
$host=substr($url,0,strpos($url,"/"));
$req=substr($url,strpos($url,"/"));
$var=fopen("out.txt","a+");
while(1){
$fp = fsockopen($host, 80, $errno, $errstr, 30);
if ($fp) {
$data = "test=1";
$request = "POST ".$req." HTTP/1.1\r\n";
$request .= "Host: ".$host."\r\n";
$request .= "Content-Length: " . strlen($data) . "\r\n";
$request .= "Content-Type: application/x-www-form-urlencoded\r\n\r\n";
$request .= $data;
fwrite($fp, $request);
while (!feof($fp)) {
$json = fgets ($fp);
echo $json;
fwrite($var, $json);
}
}
sleep(10);
fclose($fp);
}
If you want a persistent connection you should use pfsockopen instead of fsockopen. Look here for more details.
I am trying to get a response from a URL using socket programming, but nothing is working correctly. I am using PHP, and I am told by the developer I am working with that I need to open a socket, send a request, and then I should get a JSON response. the $message is the string that needs to be sent in order to receive a response.
This is what I have tried so far...
$message = "api\tjson\tget\trooms\n";
$response = fsockopen("142.4.xxx.xxx", 5678);
fputs($response, $message);
fgets($response, 2048);
$data = json_decode($response, true);
And then I go on to parse the JSON response.
I have also tried,
$message = "api\tjson\tget\trooms\n";
$response = fsockopen("142.4.xxx.xxx", 5678);
fputs($response, $message);
socket_read($response, 2048, PHP_NORMAL_READ);
$data = json_decode($response, true);
But then I get an error stating that socket_read is not the correct resource. Any help would be appreciated.
You need to do some error checking, at least. Maybe this will help:
$message = "api\tjson\tget\trooms\n";
$response = fsockopen("142.4.xxx.xxx", 5678, $errno, $errstr, 30);
if (!$response) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "POST /script.php HTTP/1.1\r\n";
$out .= "Host: www.webste.com\r\n";
$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
$out .= 'Content-Length: ' . strlen($message) . "\r\n\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($response, $out);
fwrite($response, $message);
while (!feof($response)) {
echo fgets($response, 128);
}
fclose($response);
}
i want to send post variables with fsock,
but when i try this:
$post_arr = array ("a" => "b");
$addr = 'http://1.2.3.4/confirmation.html';
$fp = fsockopen($addr, 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$req = '';
foreach ($post_arr as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&" . $key . "=" . $value;
}
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
fwrite($fp, $header);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
I get 'Unable to find the socket transport "http" ',
any ideas why?
fsockopen() opens a socket. Sockets do not know anything about Layer5+ protocols such as HTTP.
$fp = fsockopen('1.2.3.4', 80, $errno, $errstr, 30);
To request a certain path, send it in the request: GET /confirmation.html
To specify the domain, send it in the Host header: Host: 1.2.3.4
You might want to consider using the curl extension. There is usually no good reason to build HTTP requests manually in PHP.
Apologies for newbishness of this question. I'm looking into integrating one website's API into my own website. Here's some quotes from their documentation:
At the moment we only support XML,
when calling our API the HTTP Accept
header content type must be set to
“application/xml”.
The API uses the PUT request method.
I have the XML I want to send, and I have the URL I want to send it to, but how do I go about constructing a suitable HTTP Request in PHP that will also grab the XML that's returned?
Thanks in advance.
You can use file_get_contents and stream_context_create to create a request and read the response. Something like this will do it:
$opts = array(
"http" => array(
"method" => "PUT",
"header" => "Accept: application/xml\r\n",
"content" => $xml
)
);
$context = stream_context_create($opts);
$response = file_get_contents($url, false, $context);
This is actually what worked for me:
$fp = fsockopen("ssl://api.staging.example.com", 443, $errno, $errstr, 30);
if (!$fp)
{
echo "<p>ERROR: $errstr ($errno)</p>";
return false;
}
else
{
$out = "PUT /path/account/ HTTP/1.1\r\n";
$out .= "Host: api.staging.example.com\r\n";
$out .= "Content-type: text/xml\r\n";
$out .= "Accept: application/xml\r\n";
$out .= "Content-length: ".strlen($xml)."\r\n";
$out .= "Connection: Close\r\n\r\n";
$out .= $xml;
fwrite($fp, $out);
while (!feof($fp))
{
echo fgets($fp, 125);
}
fclose($fp);
}