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!
I'm using Nginx 1.7.3 and PHP 7.0.
I created a test.php file like that
<?php
$header = '';
$header .= "GET /test2.php HTTP/1.1\r\n";
$header .= "Host:127.0.0.1\r\n";
$header .= "Connection: close";
$data = $header . "\r\n\r\n";
if ($fp = fsockopen('127.0.0.1', 80))
{
fwrite($fp, $data);
$res = '';
while (!feof($fp))
{
$res .= fgets($fp, 1024);
}
fclose($fp);
}
echo $res;
?>
and I created a test2.php file like that
<?php
echo 1;
?>
then I executed the test.php file by accessing on 127.0.0.1/test.php, but It didn't working. It kept loading and didn't show any text.
so I tested like that
while (!feof($fp))
{
echo 1;
exit;
$res .= fgets($fp, 1024);
}
I excuted it, and it printed '1'.
(I think fgets() doesn't work.)
but I excuted it for a text file as follows.
$header = '';
$header .= "GET **/text.txt** HTTP/1.1\r\n";
$header .= "Host:127.0.0.1\r\n";
$header .= "Connection: close";
It works well. I don't know what I have to do. How can I use fsockopen() for PHP files on localhost. I googled about it much, but unfortunately It wasn't very helpful. If you know about that, please tell me how to do.
I'm trying to program yahoo messenger robot,now my robot can get messages and answer to them.
Yahoo only can send 100 pm at each time I get notification.
now I wanna answer the each pm. I use while(true){ } to it and answer first pm,then second ,then 3rd and ... .
It's so slow ,because I can make only one connection to yahoo by this(I use curlib).
how can I send some messages at same time?I think I need something like thread but in php.
you can use pcntl_fork(). http://www.php.net/manual/en/function.pcntl-fork.php
You need pcntl extension and it only works on Unix
If you use curl function you might take a look at curl_multi_init(). http://www.php.net/manual/en/function.curl-multi-init.php
I've wrote a simple function below, which launches URL, and doesn't wait for a result, so like this you can launch many URLs on your own site, it will make your loop fast, and also no need to install any extensions to your server.
function call_url_async($url, $params, $type='POST', $timeout_in_seconds = 1)
{
//call the URL and don't wait for the result - useful to do time-consuming tasks in background
foreach ($params as $key => &$val)
{
if (is_array($val))
$val = implode(',', $val);
$post_params[] = $key.'='.urlencode($val);
}
$post_string = implode('&', $post_params);
$parts=parse_url($url);
$fp = fsockopen($parts['host'], isset($parts['port'])?$parts['port']:80, $errno, $errstr, $timeout_in_seconds);
//if ($fp == FALSE)
// echo "Couldn't open a socket to ".$url." (".$errstr.")<br><br>";
// Data goes in the path for a GET request
if ('GET' == $type)
$parts['path'] .= '?'.$post_string;
$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";
// Data goes in the request body for a POST request
if ('POST' == $type && isset($post_string))
$out.= $post_string;
fwrite($fp, $out);
fclose($fp);
}
I am trying to send a SOAP message to a service using php.
I want to do it with fsockopen, here's is the code :
<?php
$fp = #fsockopen("ssl://xmlpropp.worldspan.com", 443, $errno, $errstr);
if (!is_resource($fp)) {
die('fsockopen call failed with error number ' . $errno . '.' . $errstr);
}
$soap_out = "POST /xmlts HTTP/1.1\r\n";
$soap_out .= "Host: 212.127.18.11:8800\r\n";
//$soap_out .= "User-Agent: MySOAPisOKGuys \r\n";
$soap_out .= "Content-Type: text/xml; charset='utf-8'\r\n";
$soap_out .= "Content-Length: 999\r\n\r\n";
$soap_put .= "Connection: close\r\n";
$soap_out .= "SOAPAction:\r\n";
$soap_out .= '
Worldspan
This is a test
';
if(!fputs($fp, $soap_out, strlen($soap_out)))
echo "could not write";
echo "<xmp>".$soap_out."</xmp>";
echo "--------------------<br>";
while (!feof($fp))
{
$soap_in .= fgets($fp, 100);
}
echo "<xmp>$soap_in</xmp>";
fclose($fp);
echo "ok";
the above code just hangs . if i remove the while it types ok, so i suppose the problem is at $soap_in .= fgets($fp, 100)
Any ideas of what is happening
Its not just a matter of opening a socket then writing 'POST....' to it - you need a full HTTP stack to parse the possible responses (e.g. what different encodings? Partial Content?). Use cURL.
The reason its currently failing is probably because the remote system is configured to use keepalives - which would again be solved by using a proper HTTP stack.
C.
I recommend, use curl for soap actions. http://www.zimbra.com/forums/developers/9890-solved-simple-soap-admin-example-php.html#post52586
I am attempting to post data using fsockopen, and then returning the result.
Here is my current code:
<?php
$data="stuff=hoorah\r\n";
$data=urlencode($data);
$fp = fsockopen("www.website.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "POST /script.php HTTP/1.0\r\n";
$out .= "Host: www.webste.com\r\n";
$out .= 'Content-Type: application/x-www-form-urlencoded\r\n';
$out .= 'Content-Length: ' . strlen($data) . '\r\n\r\n';
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
It is supposed to echo the page, and it is echoing the page, but here is the script for script.php
<?php
echo "<br><br>";
$raw_data = $GLOBALS['HTTP_RAW_POST_DATA'];
parse_str( $raw_data, $_POST );
//test 1
var_dump($raw_data);
echo "<br><br>":
//test 2
print_r( $_POST );
?>
The outcome is:
HTTP/1.1 200 OK Date: Tue, 02 Mar 2010
22:40:46 GMT Server: Apache/2.2.3
(CentOS) X-Powered-By: PHP/5.2.6
Content-Length: 31 Connection: close
Content-Type: text/html; charset=UTF-8
string(0) "" Array ( )
What do I have wrong? Why isn't the variable posting its data?
There are many small errors in your code. Here's a snippet which is tested and works.
<?php
$fp = fsockopen('example.com', 80);
$vars = array(
'hello' => 'world'
);
$content = http_build_query($vars);
fwrite($fp, "POST /reposter.php HTTP/1.1\r\n");
fwrite($fp, "Host: example.com\r\n");
fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
fwrite($fp, "Content-Length: ".strlen($content)."\r\n");
fwrite($fp, "Connection: close\r\n");
fwrite($fp, "\r\n");
fwrite($fp, $content);
header('Content-type: text/plain');
while (!feof($fp)) {
echo fgets($fp, 1024);
}
And then at example.com/reposter.php put this
<?php print_r($_POST);
When run you should get output something like
HTTP/1.1 200 OK
Date: Wed, 05 Jan 2011 21:24:07 GMT
Server: Apache
X-Powered-By: PHP/5.2.9
Vary: Host
Content-Type: text/html
Connection: close
1f
Array
(
[hello] => world
)
0
At no point is $data being written to the socket. You want to add something like:
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
fwrite($fp, $data);
Try this instead
$out .= 'Content-Length: ' . strlen($data) . '\r\n';
$out .= "Connection: Close\r\n\r\n";
$out .= $data;
Try this:
<?php
$data="stuff=hoorah\r\n";
$data=urlencode($data);
$fp = fsockopen("www.website.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "POST /script.php HTTP/1.0\r\n";
$out .= "Host: www.webste.com\r\n";
$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
$out .= 'Content-Length: ' . strlen($data) . "\r\n\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
fwrite($fp, $data);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
Some character escapes such as \n do not work in single quotes.
Nice one Tamlyn, works great!
For those that also need to send get vars along with the url,
//change this:
fwrite($fp, "POST /reposter.php HTTP/1.1\r\n");
//to:
$query = 'a=1&b=2';
fwrite($fp, "POST /reposter.php?".$query." HTTP/1.1\r\n");
Try this in reposter.php
$raw_data = $GLOBALS['HTTP_RAW_POST_DATA'];
parse_str( $raw_data, $_POST );
print_r( $_POST );
Because, the data wasn't in the $_POST[] variables but it was in the $GLOBALS['HTTP_RAW_POST_DATA'] variable.
you can use this technique it will help to call as many as pages you like all pages will run at once independently without waiting for each page response as asynchronous.
cornjobpage.php //mainpage
<?php
post_async("http://localhost/projectname/testpage.php", "Keywordname=testValue");
//post_async("http://localhost/projectname/testpage.php", "Keywordname=testValue2");
//post_async("http://localhost/projectname/otherpage.php", "Keywordname=anyValue");
//call as many as pages you like all pages will run at once independently without waiting for each page response as asynchronous.
?>
<?php
/*
* Executes a PHP page asynchronously so the current page does not have to wait for it to finish running.
*
*/
function post_async($url,$params)
{
$post_string = $params;
$parts=parse_url($url);
$fp = fsockopen($parts['host'],
isset($parts['port'])?$parts['port']:80,
$errno, $errstr, 30);
$out = "POST ".$parts['path']."?$post_string"." HTTP/1.1\r\n";//you can use GET instead of POST if you like
$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";
fwrite($fp, $out);
fclose($fp);
}
?>
testpage.php
<?
echo $_REQUEST["Keywordname"];//case1 Output > testValue
?>
PS:if you want to send url parameters as loop then follow this answer :https://stackoverflow.com/a/41225209/6295712
Curl is too heavy in some case, to use post_to_host():
//GET:
$str_rtn=post_to_host($str_url_target, array(), $arr_cookie, $str_url_referer, $ref_arr_head, 0);
//POST:
$arr_params=array('para1'=>'...', 'para2'=>'...');
$str_rtn=post_to_host($str_url_target, $arr_params, $arr_cookie, $str_url_referer, $ref_arr_head);
//POST with file:
$arr_params=array('para1'=>'...', 'FILE:para2'=>'/tmp/test.jpg', 'para3'=>'...');
$str_rtn=post_to_host($str_url_target, $arr_params, $arr_cookie, $str_url_referer, $ref_arr_head, 2);
//raw POST:
$tmp=array_search('uri', #array_flip(stream_get_meta_data($GLOBALS[mt_rand()]=tmpfile())));
$arr_params=array('para1'=>'...', 'para2'=>'...');
file_put_contents($tmp, json_encode($arr_params));
$arr_params=array($tmp);
$str_rtn=post_to_host($str_url_target, $arr_params, $arr_cookie, $str_url_referer, $ref_arr_head, 3);
//get cookie and merge cookies:
$arr_new_cookie=get_cookies_from_heads($ref_arr_head)+$arr_old_cookie;//don't change the order
//get redirect url:
$str_url_redirect=get_from_heads($ref_arr_head, 'Location');
post to host php project location: http://code.google.com/p/post-to-host/
Is using cURL and option?
Sorry for refresh, but for people who still have problem like this, change HTTP/1.0 to HTTP/1.1 and it will work.