PHP: How to track the timeout of the absence of input data? - php

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";
}
}
?>

Related

Trying to write content to a file I've created, it reads all 3 lines, but when I change the lines to read 2 it still prints out 3?

$my_content = "This is the first line\n
This is the second line\n
This is the third line\n";
$my_filename = "save.txt";
function file_writer(string $file_to_write, string $content_to_write){
$file = fopen($file_to_write, "w") or die("Unable to open file");
file_put_contents($file_to_write, $content_to_write);
fclose($file);
}
file_writer($my_filename, $my_content);
function file_reader(string $file_to_read, int $num_lines) {
$file = fopen($file_to_read, "r");
while(! feof($file))
{
$line = fgets($file);
echo $line;
}
}
**file_reader($my_filename, 3);**
Try this:
function file_reader(string $file_to_read, int $num_lines) {
$file = fopen($file_to_read, "r");
$c = 0;
while(! feof($file) && $c != $num_lines)
{
$c = $c+1;
$line = fgets($file);
echo $line;
}
}
Your other problem is that you have newlines after newlines.
$my_content = "This is the first line\nThis is the second line\nThis is the third line\n";
function file_reader(string $file_to_read, int $num_lines) {
$file = fopen($file_to_read, "r");
$currLineNo = 1;
while(!feof($file) && (currLineNo < $num_lines))
{
$line = fgets($file);
echo $line;
$currLineNo += 1;
}
}
Havent tried the code myself. This is roughly way you can stop the loop at arbitrary line number.

PHP: feof miss last word

the problem is simple but complicated at the same time.
feof doesn't print my last word. It take from file name city and code (Venice,A908) and should show in OUTPUT: nameCity,codeOfCity.
Let me show you an example:
City.csv
Abano Terme,A001
Abbadia Cerreto,A004
Abbadia Lariana,A005
Abbiategrasso,A010
Zubiena,M196
Zuccarello,M197
Zuclo,M198
Zungri,M204
Code:
<?php
$buffer = "";
$file = fopen("City.csv", "r");
//while (($c = fgetc($file)) != EOF )
//while (($c = fgetc($file)) != NULL )
//while (($c = fgetc($file)) !== false )
while(!feof($file))
{
$c = fgetc($file);
$buffer .= $c;
if($c == ",")
{
echo $buffer;
$buffer = "";
}
if($c == "\n")
{
echo $buffer."<br/>";
$buffer = "";
}
}
fclose($file);
?>
OUTPUT:
Abano Terme,A001
Abbadia Cerreto,A004
Abbadia Lariana,A005
Abbiategrasso,A010
Zubiena,M196
Zuccarello,M197
Zuclo,M198
Zungri,
Since it seems like you are just trying to output the file as is, with only change being to substitute HTML line breaks <br /> instead of new line characters why not simplify things?
echo nl2br(file_get_contents('City.csv'), true);
Or if you don't want to read the whole file into memory:
$file = fopen('City.csv', 'r');
while(!feof($file)) {
echo nl2br(fgets($file), true);
}
fclose($file);
In one of the comments above you mention that you want the city and city values available as variables (though your code example doesn't seem to indicate this). If that is the case, try fgetcsv() like this:
$file = fopen('City.csv', 'r');
while($values = fgetcsv($file)) {
$city = $values[0];
$city_code = $values[1];
echo $city . ',' . $city_code . '<br />';
}
fclose($file);
Your problem is, there's no newline at the end of your file, so it never hits the last "\n" check to output the buffer contents.
to fix this, you just need to put in another check on that conditional. change
if($c == "\n")
to:
if($c == "\n" || feof($file))
Here's a much cleaner and more concise version of your code if you'd like to use the correct function for parsing a csv file:
<?php
$buffer = array();
$file = fopen("City.csv", "r");
while(!feof($file) && $buffer[] = fgetcsv($file));
fclose($file);
foreach($buffer as $line){
echo join(',', $line).'<br/>';
}
?>

How to update files in PHP

I have some PHP function that requires the line number of a CSV file used as database. Once it has line, it navigates to the specific value that needs to be changed, changes it and rewrites the whole files. Here is my code:
<?php
function update($file, $id, $field, $value)
{
//$id is the line number
$contents = explode("\n", file_get_contents($file));
$fh = fopen($file, "w");
$lines = array();
foreach($contents as $line)
{
if($line == "")
continue;
$fields = explode("|", $line);
if($fields[0] == $id)
{
$line = null;
for($i = 0; $i<count($fields); $i++)
{
if($i == $field)
$fields[$i] = $value;
if($i != count($fields)-1)
$line .= $fields[$i]."|";
else
$line .= $fields[$i];
}
}
$line .= "\n";
fwrite($fh, $line);
}
fclose($fh);
$contents = null;
return true;
}
$id = $_SESSION['id'];
$uid = $_GET['p'];
$myfile = "myfile.txt";
if(update($myfile, 12, 14, "somevalue"))
echo "updated!";
?>
I am unable to find the problem because whenever I run the code, it outputs "updated!" just as it should but when check the file, I find it has not been updated. I do not know why, but it always remains the same! Thanks.
Check that fwrite() is not failing.
Do something like this:
...
$writeSuccess = (fwrite($fh, $line) !== false);
}
fclose($fh);
$contents = null;
return $writeSuccess;
}
...
If it is failing, check that your filesystem permissions are correctly set. The Apache user needs to have write access to whatever file/folder you are writing the file to.
I found out what the problem was.
$id = $_SESSION['id'];
$uid = $_GET['p'];
$myfile = "myfile.txt";
if(update($myfile, 12, 14, "somevalue"))
The line number pointed to the previous line, which made it impossible to update the first line of the file. So all I had to do was
$line ++;

PHP program will run and echo out nothing

I made a script that reads data from a .xls file and converts it into a .csv, then I have a script that takes the .csv and puts it in an array, and then I have a script with a foreach loop and at the end should echo out the end variable, but it echos out nothing, just a blank page. The file writes okay, and that's for sure, but I don't know if the script read the csv, because if I put an echo after it reads, it just returns blank.
Here my code:
<?php
ini_set('memory_limit', '300M');
$username = 'test';
function convert($in) {
require_once 'Excel/reader.php';
$excel = new Spreadsheet_Excel_Reader();
$excel->setOutputEncoding('CP1251');
$excel->read($in);
$x=1;
$sep = ",";
ob_start();
while($x<=$excel->sheets[0]['numRows']) {
$y=1;
$row="";
while($y<=$excel->sheets[0]['numCols']) {
$cell = isset($excel->sheets[0]['cells'][$x][$y]) ? $excel->sheets[0]['cells'][$x][$y] : '';
$row.=($row=="")?"\"".$cell."\"":"".$sep."\"".$cell."\"";
$y++;
}
echo $row."\n";
$x++;
}
return ob_get_contents();
ob_end_clean();
}
$csv = convert('usage.xls');
$file = $username . '.csv';
$fh = fopen($file, 'w') or die("Can't open the file");
$stringData = $csv;
fwrite($fh, $stringData);
fclose($fh);
$maxlinelength = 1000;
$fh = fopen($file);
$firstline = fgetcsv($fh, $maxlinelength);
$cols = count($firstline);
$row = 0;
$inventory = array();
while (($nextline = fgetcsv($fh, $maxlinelength)) !== FALSE )
{
for ( $i = 0; $i < $cols; ++$i )
{
$inventory[$firstline[$i]][$row] = $nextline[$i];
}
++$row;
}
fclose($fh);
$arr = $inventory['Category'];
$texts = 0;
$num2 = 0;
foreach($inventory['Category'] as $key => $value) {
$val = $value;
if (is_object($value)) { echo 'true'; }
if ($value == 'Messages ') {
$texts++;
}
}
echo 'You have used ' . $texts . ' text messages';
?>
Once you return. you cannot do anything else in the function:
return ob_get_contents();
ob_end_clean();//THIS NEVER HAPPENS
Therefore the ob what never flushed and won't have any output.
I see a lot of repetitive useless operations there. Why not simply build an array with the data you're pulling out of the Excel file? You can then write out that array with fputcsv(), instead of building the CSV string yourself.
You then write the csv out to a file, then read the file back in and process it back into an array. Which begs the question... why? You've already got the raw individual bits of data at the moment you read from the excel file, so why all the fancy-ish giftwrapping only to tear it all apart again?

invalid arguments foreach in php in commandline

I wrote a script in php which reads two files and takes all the strings from one file and searches them in other file. This is working fine in web browser. But when I try to run it through command line, it says
'invalid arguments supplied for foreach() at line....'
am I missing anything?
<?php
$filename = 'search_items.txt';
$fp = #fopen($filename, 'r');
if ($fp) {
$array = explode(",", fread($fp, filesize($filename)));
}
$filename1 = 'file1.log';
$fp1 = #fopen($filename1, 'r');
if ($fp1) {
$array1 = explode("\n", fread($fp1, filesize($filename1)));
}
$num = 1;
foreach($array1 as $val1){
foreach($array as $val){
if(strstr($val1, $val)){
echo 'line : '.$num.'->'.$val1.'<br>';
}
}
++$num;
}
?>
<?php
$filename = 'search_items.txt';
$fp = fopen($filename, 'r');
if ($fp) {
$array = explode(",", fread($fp, filesize($filename)));
}
$filename1 = 'file1.log';
$fp1 = fopen($filename1, 'r');
if ($fp1) {
$array1 = explode("\n", fread($fp1, filesize($filename1)));
}
$num = 1;
foreach($array1 as $val1)
{
foreach($array as $val)
{
if(strstr($val1, $val))
{
print_r('\n'); //2
}
}
++$num;
print_r($val1); // 1
}
Ok, the script is running now, but with something funny going on.
if I remove the print in comment 1 and place it in comment 2 place, the results I am getting is the last result , i.e just one last result. not the full searches. Can anyone tell me why?
Your fopen calls are not finding their file, I imagine. First, remove the '#' from '#fopen', so you can see it fail. Then, do this:
$filename = dirname(__FILE__).'/search_items.txt';
//...
$filename1 = dirname(__FILE__).'/file1.log';
That will keep your file locations straight.
Probably your file paths are off, so $array and $array1 are never created. Relative paths will be from where you call the script, not the location of the script.
Maybe variables are empty or not exist?
$array = $array1 = array();
//...
foreach((array)$array1 as $val1)
{
foreach((array)$array as $val)
{
if(strstr($val1, $val))
{
echo 'line : '.$num.'->'.$val1.'<br>';
}
}
$num++;
}
To be on the safe side you should add a check if the file pointers are valid before running the foreach loops, or throw some errors if you fail to open a file.
<?php
$filename = 'search_items.txt';
$fp = #fopen($filename, 'r');
if ($fp) {
$array = explode(",", fread($fp, filesize($filename)));
}
$filename1 = 'file1.log';
$fp1 = #fopen($filename1, 'r');
if ($fp1) {
$array1 = explode("\n", fread($fp1, filesize($filename1)));
}
$num = 1;
if($fp && $fp1)
{
foreach($array1 as $val1)
{
foreach($array as $val)
{
if(strstr($val1, $val))
{
echo 'line : '.$num.'->'.$val1.'<br>';
}
}
++$num;
}
}
?>
Keep in mind that when running a script from CLI, the current directory is the directory from which the script was started. When running trough Apache, the current directory is the directory of the script. This bit me a couple of times.

Categories