PHP fire and forget not working with remote server - php

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

curl or file_get_contents ignore output

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);
}

Persistent connections

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.

Socket programming: socket_read, fgets cannot get response

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);
}

fsock: Unable to find the socket transport "http"

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.

Making a REST API request 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);
}

Categories