I have a socket client that would read data from the server.
However, it does not leave the do..while loop as soon as there are no more data left to read? why is that so? Thanks
while (true)
{
$data_old=$data;
$data = file_get_contents("userInput.txt");
if($data_old != $data)
{
socket_write($socket, $data, strlen($data));
do
{
$line =#socket_read($socket,2048);
echo $line. "\n";
}
while($line != "");
}
}
I believe your problem is that the execution never leaves the while (true) loop and not the while($line != "") one, try this:
while (true)
{
$data_old = $data;
$data = file_get_contents('userInput.txt');
if ($data_old != $data)
{
socket_write($socket, $data, strlen($data));
while (true)
{
$line = #socket_read($socket, 2048);
echo $line. "\n";
if ($line == '')
{
break 2;
}
}
}
}
Is the socket is non-blocking you may also want to use socket_select() with a timeout.
i solved it using another method. By my server sending a (" ") statement to the client after all the data has been sent.
Client side will then exit that loop upon receiving the statement.
while (true)
{
$data_old=$data;
$data = file_get_contents("userInput.txt");
if($data_old != $data)
{
socket_write($socket, $data, strlen($data));
do
{
$line =#socket_read($socket,2048);
if($line != " ")
echo $line. "\n";
}
while($line != " ");
}
}
Related
There is code which recieves input lines from STDIN:
#!/usr/bin/php
<?php
while (false !== ($line = fgets(STDIN))) {
if (preg_match('/start/',$line)) {
echo $line , "\n";
}
}
?>
My question is: how to track the timeout of the absence of input data for 1 minute and inform if in case?
I resolved my issue using answer of hek2mgl from here [PHP CLI - Ask for User Input or Perform Action after a Period of Time
This is my code :
#!/usr/bin/php
<?php
echo "input something ... (5 sec)\n";
$stdin = fopen('php://stdin', 'r');
while(true) {
$read = array($stdin);
$write = $except = array();
$timeout = 5;
if(stream_select($read, $write, $except, $timeout)) {
$line = fgets($stdin);
if (preg_match('/start/',$line)) {
echo $line , "\n";
}
} else {
echo "you typed nothing\n";
}
}
?>
I want to check if a string exists within a text file and if it exists, return the message string exists. If it does not exist, add the string to the file and return string added.
I got it working with no message:
<?php
$path = '../test/usersBlacklist.txt';
$input = $_POST["id"];
if ($input) {
$handle = fopen($path, 'r+');
while (!feof($handle)) {
$value = trim(fgets($handle));
if ($value == $input) {
return false;
}
}
fwrite($handle, $input);
fclose($handle);
return true;
}
if (true) {
echo 'added';
} else {
echo 'exists';
}
?>
As #NigelRen mentioned use answer from this question and then use this to append:
if( strpos(file_get_contents($path),$input) !== false) {
echo "found it";
}
else{
file_put_contents($path, $input, FILE_APPEND | LOCK_EX);
echo "added string";
}
This code has no sense, a solution is maybe to create a function :
function checkI($input) {
$handle = fopen($path, 'r+');
while (!feof($handle)) {
$value = trim(fgets($handle));
if ($value == $input) {
return false;
}
}
fwrite($handle, $input);
fclose($handle);
return true;
}
and then:
if (checkI($input)) {
echo 'added';
} else {
echo 'exists';
}
Your if(true) , it ll be always true.
If you are trying to append some value to a file that already has some data in it than it would be better to use "a+" flag instead of "r+"
As noted in the php docs:
'a+' Open for reading and writing; place the file pointer at the end of the file. If the file does not exist, attempt to create it. In this mode, fseek() only affects the reading position, writes are always appended.
More info here: https://secure.php.net/manual/en/function.fopen.php
And also like CBroe said using return outside of a function won't help you a better way would be something like this:
$input = $_POST["id"];
function doesLineExist($input){
$path = '../test/usersBlacklist.txt';
if ($input) {
$handle = fopen($path, 'r+');
while (!feof($handle)) {
$value = trim(fgets($handle));
if ($value == $input) {
return false;
}
}
fwrite($handle, $input);
fclose($handle);
return true;
}
}
$doesExist = doesLineExist($input);
if($doesExist){
echo "Added"
}else{
echo "Exists"
}
i have a script where i use die to prevent a function's continuous loop. But if i place this above the html, the html script will stop as well so i place it below the html but all the variables get echoed below the actual website. How can i make sure this get's echoed to the place where i want it to be and not below the website? Or is there a different way than using die? This is the code of the function:
function QueryWhoisServer($whoisserver, $domain) {
$port = 43;
$timeout = 5;
$errm = "<p1>No connection could be made</p1>";
$fp = #fsockopen($whoisserver, $port, $errno, $errstr, $timeout) or die($errm);
fputs($fp, $domain . "\r\n");
$out = "";
while (!feof($fp)) {
$out .= fgets($fp);
}
fclose($fp);
$res = "";
if((strpos(strtolower($out), "error") === FALSE) && (strpos(strtolower($out), "not allocated") === FALSE)) {
$rows = explode("\n", $out);
foreach($rows as $row) {
$row = trim($row);
if(($row != ':') && ($row != '#') && ($row != '%')) {
$res .= $row."<br>";
}
}
}
return $res;
}
The keyword break breaks out of any loop, just use it instead of die.
Beware if you have nested loops, as break will only exit the innermost loop. Oddly enough, in php you can use break(2) to break from two loops. I would refrain from doing that though.
die(); stops all PHP execution. It's rare that you'd actually want to do that.
Instead you should look at the try - catch construct and throwing and catching exceptions.
function QueryWhoisServer($whoisserver, $domain) {
try {
$port = 43;
$timeout = 5;
$errm = "<p1>No connection could be made</p1>";
$fp = #fsockopen($whoisserver, $port, $errno, $errstr, $timeout);
if (!fp) {
throw new Exception ("Couldn't open socket.");
}
//after the exception is thrown, the rest of this block will not execute.
fputs($fp, $domain . "\r\n");
$out = "";
while (!feof($fp)) {
$out .= fgets($fp);
}
fclose($fp);
$res = "";
if((strpos(strtolower($out), "error") === FALSE) && (strpos(strtolower($out), "not allocated") === FALSE)) {
$rows = explode("\n", $out);
foreach($rows as $row) {
$row = trim($row);
if(($row != ':') && ($row != '#') && ($row != '%')) {
$res .= $row."<br>";
}
}
}
return $res;
} catch (Exception $e) {
//this block will be executed if any Exception is caught, including the one we threw above.
//you can handle the error here or rethrow it to pass it up the execution stack.
return "";
}
}
PHP's Exceptions manual page
You can use a control variable to avoid infinite looping.
$end_condition = false;
while (!$end_condition)
{
//do the job
if (conditions/are/met)
{
$end_condition = true;
}
}
Is there any way (other than checking for ping responses) to detect when a client stream (I don't know if a stream would be any different from sockets) becomes unavailable (ie there is no longer any connection but no clean disconnection was made)?
Using this code:
#!/usr/bin/env php
<?php
$socket = stream_socket_server(
'tcp://192.168.1.1:47700',
$errno,
$errstr,
STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,
stream_context_create(
array(),
array()
)
);
if (!$socket) {
echo 'Could not listen on socket'."\n";
}
else {
$clients = array((int)$socket => $socket);
$last = time();
while(true) {
$read = $clients;
$write = null;
$ex = null;
stream_select(
$read,
$write,
$ex,
5
);
foreach ($read as $sock) {
if ($sock === $socket) {
echo 'Incoming on master...'."\n";
$client = stream_socket_accept(
$socket,
5
);
if ($client) {
stream_set_timeout($client, 1);
$clients[(int)$client] = $client;
}
}
else {
echo 'Incoming on client '.((int)$sock)."...\n";
$length = 1400;
$remaining = $length;
$buffer = '';
$metadata['unread_bytes'] = 0;
do {
if (feof($sock)) {
break;
}
$result = fread($sock, $length);
if ($result === false) {
break;
}
$buffer .= $result;
if (feof($sock)) {
break;
}
$continue = false;
if (strlen($result) == $length) {
$continue = true;
}
$metadata = stream_get_meta_data($sock);
if ($metadata && isset($metadata['unread_bytes']) && $metadata['unread_bytes']) {
$continue = true;
$length = $metadata['unread_bytes'];
}
} while ($continue);
if (strlen($buffer) === 0 || $buffer === false) {
echo 'Client disconnected...'."\n";
stream_socket_shutdown($sock, STREAM_SHUT_RDWR);
unset($clients[(int)$sock]);
}
else {
echo 'Received: '.$buffer."\n";
}
echo 'There are '.(count($clients) - 1).' clients'."\n";
}
}
if ($last < (time() - 5)) {
foreach ($clients as $id => $client) {
if ($client !== $socket) {
$text = 'Yippee!';
$ret = fwrite($client, $text);
if ($ret !== strlen($text)) {
echo 'There seemed to be an error sending to the client'."\n";
}
}
}
}
}
}
if ($socket) {
stream_socket_shutdown($socket, STREAM_SHUT_RDWR);
}
and a sockets client on a different computer, I can connect to the server, send and receive data, and disconnect cleanly and everything functions as expected. If, however, I pull the network connection on the client computer, nothing is detected on the server side - the server keeps on listening to the client socket, and also writes to it without any error manifesting itself.
As I understand it, calling feof($stream) will tell you if the remote socket disconnected, but I'm not absolutely certain about that. I'm using ping/pong myself while continuing to research a solution.
You need to set a socket timeout, in which case you get an error if a client does not respond in a timely fashion.
Check PHP's stream_set_timeout function:
http://www.php.net/manual/en/function.stream-set-timeout.php
Also check socket_set_option:
http://php.net/manual/en/function.socket-set-option.php
and finally, check out this great article on how to use sockets in PHP effectively:
"PHP Socket Programming, done the Right Way™"
http://christophh.net/2012/07/24/php-socket-programming/
I'm trying to search a PHP file for a string and when that string is found I want to return the whole LINE that the string is on. Here is my example code. I'm thinking I would have to use explode but cannot figure that out.
$searchterm = $_GET['q'];
$homepage = file_get_contents('forms.php');
if(strpos($homepage, "$searchterm") !== false)
{
echo "FOUND";
//OUTPUT THE LINE
}else{
echo "NOTFOUND";
}
Just read the whole file as array of lines using file function.
function getLineWithString($fileName, $str) {
$lines = file($fileName);
foreach ($lines as $lineNumber => $line) {
if (strpos($line, $str) !== false) {
return $line;
}
}
return -1;
}
You can use fgets() function to get the line number.
Something like :
$handle = fopen("forms.php", "r");
$found = false;
if ($handle)
{
$countline = 0;
while (($buffer = fgets($handle, 4096)) !== false)
{
if (strpos($buffer, "$searchterm") !== false)
{
echo "Found on line " . $countline + 1 . "\n";
$found = true;
}
$countline++;
}
if (!$found)
echo "$searchterm not found\n";
fclose($handle);
}
If you still want to use file_get_contents(), then do something like :
$homepage = file_get_contents("forms.php");
$exploded_page = explode("\n", $homepage);
$found = false;
for ($i = 0; $i < sizeof($exploded_page); ++$i)
{
if (strpos($buffer, "$searchterm") !== false)
{
echo "Found on line " . $countline + 1 . "\n";
$found = true;
}
}
if (!$found)
echo "$searchterm not found\n";
If you use file rather than file_get_contents you can loop through an array line by line searching for the text and then return that element of the array.
PHP file documentation
You want to use the fgets function to pull an individual line out and then search for the
<?PHP
$searchterm = $_GET['q'];
$file_pointer = fopen('forms.php');
while ( ($homepage = fgets($file_pointer)) !== false)
{
if(strpos($homepage, $searchterm) !== false)
{
echo "FOUND";
//OUTPUT THE LINE
}else{
echo "NOTFOUND";
}
}
fclose($file_pointer)
Here is an answered question about using regular expressions for your task.
Get line number from preg_match_all()
Searching a file and returning the specified line numbers.