How to print the last string from socket - php

I'm trying to print the last string from server respone. I'm write the following:
$fp = fsockopen("smtp.mail.ru", 25);
// There is fputs functions
echo fgets($fp);// This is print the first string
But I want to print the last string of the server's response. Is it possible to do?

You can put the strings into array of stings, then print the last string:
<?php
$cntr = 0;
$strarray = [];
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp)
{
echo "$errstr ($errno)<br />\n";
}
else
{
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp))
{
$strarray[$cntr] = fgets($fp);
$cntr = $cntr + 1;
}
fclose($fp);
}
//Now, print the last string in the array:
echo end($strarray);
?>

Related

PHP : echo not working in infinite while loop

I want to show $input from the client using echo on the server side.
PHP Server:
<?php
$socket = stream_socket_server("tcp://127.0.0.1:8000", $errno, $errstr);
if (!$socket) {
echo "$errstr ($errno)<br />\n";
} else {
while ($conn = stream_socket_accept($socket)) {
$input = fread($conn, 1024);
echo $input;
fwrite($conn, 'Wait for a while... ' . $input);
fclose($conn);
}
fclose($socket);
}
fwrite() successfully writes $input to client but echo $input displaying nothing.
You should use flush():
<?php
$socket = stream_socket_server("tcp://127.0.0.1:8000", $errno, $errstr);
if (!$socket) {
echo "$errstr ($errno)<br />\n";
} else {
while ($conn = stream_socket_accept($socket)) {
$input = fread($conn, 1024);
echo $input;
ob_flush();
flush();
fwrite($conn, 'Wait for a while... ' . $input);
fclose($conn);
}
fclose($socket);
}

how to accept multiple connection to the device

I am creating a socket script that will listen to our 3 devices.and the device is setup in one server ip and one port only.
$file = fopen('txt.log','a+');
$server = stream_socket_server('tcp://'.$ipserver.':'.$port, $errno, $errorMessage);
if(!$server) {
echo "$errorMessage ($errno)<br />\n";
}
else{
while($client = #stream_socket_accept($server,$timeout)) {
stream_copy_to_stream($client, $file);
fclose($file);
fclose($client);
}
}
but the problem is that if one device is connected,the two devices cannot connect anymore.I appreciate some one can help me how to get this work.or give me some idea
Thank you in advance.
$file = fopen('txt.log', 'a+');
$server = stream_socket_server("tcp://$ipserver:$port", $errno, $errorMessage);
if (!$server)
echo "$errorMessage ($errno)<br />\n";
else
{
$s = array($server);
$t = $timeout == -1 ? NULL : $timeout;
while ($r = $s and stream_select($r, $n=NULL, $n=NULL, $t))
foreach ($r as $stream)
if ($stream == $server) // new client
$s[] = stream_socket_accept($server, -1);
else
if (!fputs($file, fgets($stream)))
{
fclose($stream);
array_splice($s, array_search($stream, $s), 1);
}
}

How Do I use curl_post_async() to Run PHP Script in the Background?

I expected the followingcode would create a file, test.txt, in the same directory of the loading script when the page is accessed. But it doesn't. Nothing happens. Could somebody tell what is wrong with this code? Does it work fine in your environment?
<?php
if (isset($_POST['cache']) && $_POST['cache'] === true) {
$file = dirname(__FILE__) . '/test.txt';
$current = time() . ": John Smith\r\n";
file_put_contents($file, $current,FILE_APPEND);
return;
}
curl_post_async(selfurl(), array('cache' => true));
echo 'writing a log in the background.<br />';
return;
function curl_post_async($url, $params) {
//http://stackoverflow.com/questions/124462/asynchronous-php-calls
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, 30);
$out = "POST ".$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";
if (isset($post_string)) $out.= $post_string;
fwrite($fp, $out);
fclose($fp);
}
function selfurl() {
// http://www.weberdev.com/get_example.php3?ExampleID=4291
$s = empty($_SERVER["HTTPS"]) ? '' : ($_SERVER["HTTPS"] == "on") ? "s" : "";
$protocol = strleft(strtolower($_SERVER["SERVER_PROTOCOL"]), "/").$s;
$port = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":".$_SERVER["SERVER_PORT"]);
return $protocol."://".$_SERVER['SERVER_NAME'].$port.$_SERVER['REQUEST_URI'];
}
function strleft($s1, $s2) {
return substr($s1, 0, strpos($s1, $s2));
}
?>
Problem
The error in your script is in the following
if (isset($_POST['cache']) && $_POST['cache'] === true) {
$file = dirname(__FILE__) . '/test.txt';
$current = time() . ": John Smith\r\n";
file_put_contents($file, $current,FILE_APPEND);
return;
}
$_POST['cache'] === true would try to validated of cache with same type as boolean but $_POST['cache'] would actually output 1 when posted over http using current method
Solution
if (isset($_POST['cache'])) {
if ($_POST['cache'] == true) {
$file = dirname(__FILE__) . '/test.txt';
$current = time() . ": John Smith\r\n";
file_put_contents($file, $current, FILE_APPEND);
}
return ;
}

Adding an Array to a php script

I have a script that checks a website ($host) for an string of characters ($find). If the string exists the nothing happens, if the string is not found then an email is sent to a pre-set email address.
The problem I have is that I need to have an array of URL's and I believe a second array of text. The text in the array needs to match up to the URL's in the array.
Perhaps storing the URL's and text in a text file(s) might be a better solution.
Here is the script as it is right now, working on the single domain.
<?php
$host = 'www.my-domain.com';
$find = 'content on my page';
function check($host, $find) {
$fp = fsockopen($host, 80, $errno, $errstr, 10);
if (!$fp) {
echo "$errstr ($errno)\n";
} else {
$header = "GET / HTTP/1.1\r\n";
$header .= "Host: $host\r\n";
$header .= "Connection: close\r\n\r\n";
fputs($fp, $header);
while (!feof($fp)) {
$str.= fgets($fp, 1024);
}
fclose($fp);
return (strpos($str, $find) !== false);
}
}
function alert($host) {
mail('mail#my-domain.com', 'Monitoring', $host.' down');
}
if (!check($host, $find)) alert($host);
?>
New code with array in place:
$hostMap = array(
'www.my-domain.com' => 'content on site',
'www.my-domain2.ca' => 'content on second site',
);
foreach ($hostMap as $host => $find)
{
function check($host, $find)
{
$fp = fsockopen($host, 80, $errno, $errstr, 10);
if (!$fp)
{
echo "$errstr ($errno)\n";
} else {
$header = "GET / HTTP/1.1\r\n";
$header .= "Host: $host\r\n";
$header .= "Connection: close\r\n\r\n";
fputs($fp, $header);
while (!feof($fp)) {
$str.= fgets($fp, 1024);
}
fclose($fp);
return (strpos($str, $find) !== false);
}
}
function alert($host)
{
mail('my-email#my-domain.com', 'Website Monitoring', $host.' is down');
}
print $host;
print $find;
//if (!check($host, $find)) alert($host);
if( !check( $host, $find ) )
{
alert($host);
}
}
?>
Moved the functions outside of the foreach(
ini_set( 'display_errors', true );
$hostMap = array(
'www.my-domain.com' => 'content on site',
'www.my-domain2.ca' => 'content on second site',
);
function check($host, $find)
{
$fp = fsockopen($host, 80, $errno, $errstr, 10);
if (!$fp)
{
echo "$errstr ($errno)\n";
} else {
$header = "GET / HTTP/1.1\r\n";
$header .= "Host: $host\r\n";
$header .= "Connection: close\r\n\r\n";
fputs($fp, $header);
while (!feof($fp)) {
$str.= fgets($fp, 1024);
}
fclose($fp);
return (strpos($str, $find) !== false);
}
}
function alert($host)
{
mail('my-email#my-domain.com', 'Website Monitoring', $host.' is down');
}
print $host;
print $find;
//if (!check($host, $find)) alert($host);
foreach ($hostMap as $host => $find)
{
if( !check( $host, $find ) )
{
alert($host);
}
}
?>
Here is the final code with a working Array in case anyone else wants a solution like this.
function check($host, $find)
{
$fp = fsockopen($host, 80, $errno, $errstr, 10);
if (!$fp)
{
echo "$errstr ($errno)\n";
} else {
$header = "GET / HTTP/1.1\r\n";
$header .= "Host: $host\r\n";
$header .= "Connection: close\r\n\r\n";
fputs($fp, $header);
while (!feof($fp)) {
$str.= fgets($fp, 1024);
}
fclose($fp);
return (strpos($str, $find) !== false);
}
}
function alert($host)
{
$headers = 'From: Set your from address here';
mail('my-email#my-domain.com', 'Website Monitoring', $host.' is down' $headers);
}
$hostMap = array(
'www.my-domain.com' => 'content on site',
'www.my-domain2.com' => 'content on second site',
);
//if (!check($host, $find)) alert($host);
foreach ($hostMap as $host => $find)
{
if( !check( $host, $find ) )
{
alert($host);
}
}
unset($host);
unset($find);
?>
$hostMap = array(
'www.my-domain.com' => 'content on my page',
/* etc. */
);
foreach( $hostMap as $host => $find )
{
if( !check( $host, $find ) )
{
alert($host);
}
}
However, be aware that -- depending on the amount of domains you are checking -- sequentially mailing large amounts of mails with PHP's native mail() is not very efficient. You may wanna look in to more specialized mail libraries for that, such as SwiftMailer.
On the other hand -- seeing you are mailing one and the same e-mail address -- you could also simply save the failing domains in an array, and mail them all in one e-mail after you're done checking of course.
You can just store everything in a multidimensional array and put an iterator around the entire working section of code.
$list_of_sites[0]["url"] = blah;
$list_of_sites[0]["text"] = blah;
$list_of_sites[1]["url"] = blah;
$list_of_sites[1]["text"] = blah;
foreach($list_of_sites as $site){
$url = $site["url"];
$text = $site["text"];
check($url, $text);
}

PHP Infine Loop Problem

function httpGet( $url, $followRedirects=true ) {
global $final_url;
$url_parsed = parse_url($url);
if ( empty($url_parsed['scheme']) ) {
$url_parsed = parse_url('http://'.$url);
}
$final_url = $url_parsed;
$port = $url_parsed["port"];
if ( !$port ) {
$port = 80;
}
$rtn['url']['port'] = $port;
$path = $url_parsed["path"];
if ( empty($path) ) {
$path="/";
}
if ( !empty($url_parsed["query"]) ) {
$path .= "?".$url_parsed["query"];
}
$rtn['url']['path'] = $path;
$host = $url_parsed["host"];
$foundBody = false;
$out = "GET $path HTTP/1.0\r\n";
$out .= "Host: $host\r\n";
$out .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0\r\n";
$out .= "Connection: Close\r\n\r\n";
if ( !$fp = #fsockopen($host, $port, $errno, $errstr, 30) ) {
$rtn['errornumber'] = $errno;
$rtn['errorstring'] = $errstr;
}
fwrite($fp, $out);
while (!#feof($fp)) {
$s = #fgets($fp, 128);
if ( $s == "\r\n" ) {
$foundBody = true;
continue;
}
if ( $foundBody ) {
$body .= $s;
} else {
if ( ($followRedirects) && (stristr($s, "location:") != false) ) {
$redirect = preg_replace("/location:/i", "", $s);
return httpGet( trim($redirect) );
}
$header .= $s;
}
}
fclose($fp);
return(trim($body));
}
This code sometimes go infinite loop. What's wrong here?
There is a big, red warning box in the feof() documentation:
Warning
If a connection opened by fsockopen() wasn't closed by the server, feof() will hang. To workaround this, see below example:
Example #1 Handling timeouts with feof()
<?php
function safe_feof($fp, &start = NULL) {
$start = microtime(true);
return feof($fp);
}
/* Assuming $fp is previously opened by fsockopen() */
$start = NULL;
$timeout = ini_get('default_socket_timeout');
while(!safe_feof($fp, $start) && (microtime(true) - $start) < $timeout)
{
/* Handle */
}
?>
Also you should only write to or read from the file pointer, if it is valid (what you are not doing, you just set an error message):
This leads to the second big red warning box:
Warning
If the passed file pointer is not valid you may get an infinite loop, because feof() fails to return TRUE.
Better would be:
$result = '';
if ( !$fp = #fsockopen($host, $port, $errno, $errstr, 30) ) {
$rtn['errornumber'] = $errno;
$rtn['errorstring'] = $errstr;
}
else {
fwrite($fp, $out);
while (!#feof($fp)) {
//...
}
fclose($fp);
$result = trim(body);
}
return $result;
A last remark: If you follow a redirect with
if ( ($followRedirects) && (stristr($s, "location:") != false) ) {
$redirect = preg_replace("/location:/i", "", $s);
return httpGet( trim($redirect) );
}
you never close the file pointer. I think better is:
if ( ($followRedirects) && (stristr($s, "location:") != false) ) {
$redirect = preg_replace("/location:/i", "", $s);
$result = httpGet( trim($redirect) );
break;
}
// ...
return $result;
feof will return false if the connection is still open in a tcp/ip stream.
function httpGet( $url, $followRedirects=true ) {
[...]
return httpGet( trim($redirect) );
}
Nothing prevents you from fetching the same URL again and again.

Categories