PHP - Incrementing multiple values in a text file with explode - php

I'm trying to increment a counter inside a text file, that counts HTTP responses from some APIs. This part is handled correctly at the moment. The issue I'm having is that when my text file has more than two values that need to be incremented, only one of the fields is updated and I'm not sure what the structure of the explode should be to update the other value.
The structure of the text file is:
api:one
success:1
fail:1
and no matter what response is received, only the fail is updated.
The code section I have at the moment is:
if ($status == "6" OR $status == "2") {
$filename = '/home/path/to/file/'.basename(__DIR__).'-responses.txt';
$lines = file($filename);
if(!is_file($filename)){
$default = 'api:one' . "\n" . 'success:1' . "\n" . 'fail:1';
file_put_contents($filename, $default);
} else {
foreach ($lines as $k=>$v) {
$exploded = explode(":", $v);
if ($exploded[0] == "fail") {
$exploded[1]++;
$lines[$k] = implode(":", $exploded);
}
}
file_put_contents($filename, $lines);
}
} else {
$filename = '/home/path/to/file/'.basename(__DIR__).'-responses.txt';
$lines = file($filename);
if(!is_file($filename)){
$default = 'api:one' . "\n" . 'success:1' . "\n" . 'fail:1';
file_put_contents($filename, $default);
} else {
foreach ($lines as $k=>$v) {
$exploded = explode(":", $v);
if ($exploded[0] == "success") {
$exploded[1]++;
$lines[$k] = implode(":", $exploded);
}
}
file_put_contents($filename, $lines);
}
}

The problem is that you're not removing the newlines from the lines before you try to increment the numbers. The success line has a newline at the end, and when you try to increment "1\n" it doesn't do anything, since that's not a number.
Use the FILE_IGNORE_NEW_LINES option to remove the newlines when creating the array, then add them back when writing back to the file.
if ($status == "6" OR $status == "2") {
$filename = '/home/path/to/file/'.basename(__DIR__).'-responses.txt';
if(!is_file($filename)){
$default = 'api:one' . "\n" . 'success:1' . "\n" . 'fail:1';
file_put_contents($filename, $default);
} else {
$lines = file($filename, FILE_IGNORE_NEW_LINES);
foreach ($lines as $k=>$v) {
$exploded = explode(":", $v);
if ($exploded[0] == "fail") {
$exploded[1]++;
$lines[$k] = implode(":", $exploded);
}
}
file_put_contents($filename, implode("\n", $lines));
}
} else {
$filename = '/home/path/to/file/'.basename(__DIR__).'-responses.txt';
if(!is_file($filename)){
$default = 'api:one' . "\n" . 'success:1' . "\n" . 'fail:1';
file_put_contents($filename, $default);
} else {
$lines = file($filename, FILE_IGNORE_NEW_LINES);
foreach ($lines as $k=>$v) {
$exploded = explode(":", $v);
if ($exploded[0] == "success") {
$exploded[1]++;
$lines[$k] = implode(":", $exploded);
}
}
file_put_contents($filename, implode("\n", $lines));
}
}
Also, you should do the check for whether the file exists before you try to read the file.

Related

fopen is duplicating the same line

I have a file that looks like this:
1||Allan||34||male||USA||||55.789.980
2||Georg||32||male||USA||||55.756.180
3||Rocky||21||male||USA||[100][200]||55.183.567
I made a function that when executed adds a given number or removes it if already present, which is $added and equals 100 for this example. This is my code:
$added = $_GET['added']; //100 for this example
$f = fopen($file, "w");
$list = file($file);
foreach ($list as $line) {
$details = explode("||", $line);
if (preg_match("~\b$details[0]\b~", 3)) {
foreach ($details as $key => $value) {
if ($key == 5) {
$newline .= str_replace("[" . $added . "]", "", $value);
} else {
$newline .= $value . "||";
}
}
$line = $newline . "\n";
}
fputs($f, $line);
}
fclose($f);
}
this code is supposed to remove the [100] from the Rocky line since its already present which it kinda does. However, upon further execution instead of adding it back it duplicates the Rocky line and messes it up so the file looks like this:
1||Allan||34||male||USA||||55.789.980
2||Georg||32||male||USA||||55.756.180
3||Rocky||21||male||USA||[100][200]55.183.567
3||Rocky||21||male||USA||[100][200]55.183.567
||
||
why is it doing this? I cant make any sense out of it...
Thank you.
First, you should read the file before you open it for output, because opening with the w mode truncates the file.
Second, you don't need to loop over the fields in $details if you just want to change one of them. Just access and assign it by index.
Then you can put the line back together with implode().
$list = file($file);
$f = fopen($file, "w");
foreach ($list as $line) {
$details = explode("||", $line);
if (preg_match("~\b$details[0]\b~", 3)) {
if (strpos("[$added]", $details[5]) === false) {
$details[5] = "[$added]" . $details[5];
} else {
$details[5] = str_replace("[$added]", "", $details[5]);
}
$line = implode('||', $details)
}
fputs($f, $line);
}
fclose($f);

PHP Add or Edit line in text File

I'm trying to search a text file, if a line contains a specific key ID I want to update the entire line, if not add a new line.
So based on this text file :
admin,1234,ID1345,NW
staff,1325,ID1001,NE
staff,2157,ID2003,SW
staff,8519,ID3001,NS
I want to search for ID1345 and then update that line only, the other lines stay exactly as they are. If no lines contain ID1345 then add a new line to the text file.
So far I've got:
$search = 'ID1345';
$result = 'admin,6698,ID1345,OP';
$reading = fopen('myfile', 'r');
$writing = fopen('myfile.tmp', 'w');
$replaced = false;
while (!feof($reading)) {
$line = fgets($reading);
if (stristr($line, $search)) {
$line = "$result\n";
$replaced = true;
}
fputs($writing, $line);
}
if (!$replaced) fputs($writing, "$result\n");
fclose($reading); fclose($writing);
rename('myfile.tmp', 'myfile');
This seems to work for the find and replace, but if the line doesn't exist it keeps adding it not just once.
I know this is due to the if (!$replaced) line, but I'm not sure how to do this.
The example above is small, but there could be a few thousand entries in the file..
Thanks
function file_properties($fileProperties) {
$result = array();
$lines = split("\n", $fileProperties);
$key = "";
$isWaitingOtherLine = false;
foreach($lines as $i=>$line) {
if(empty($line) || (!$isWaitingOtherLine && strpos($line,"#") === 0)) continue;
if(!$isWaitingOtherLine) {
$key = substr($line,0,strpos($line,'='));
$value = substr($line,strpos($line,'=') + 1, strlen($line));
} else {
$value .= $line;
}
/* Check if ends with single '\' */
if(strrpos($value,"\\") === strlen($value)-strlen("\\")) {
$value = substr($value, 0, strlen($value)-1)."\n";
$isWaitingOtherLine = true;
} else {
$isWaitingOtherLine = false;
}
$result[$key] = $value;
unset($lines[$i]);
}
return $result;
}
This will read and write values to file with any extension like .env in Laravel or anything *.properties in Java

PHP excel file without PHPExcel

I have to create a excel file having near about 350 columns and 1000 rows. I have developed code for this task using PHPExcel. But it takes 42secs to create file. So I have to create excel file without PHPExcel. So I have developed a script in which data is identified by "\t" for different tab data. It takes just 2secs to create file. But problem is that when I'm going to open that file (created by using "\t"), message of corrupted file is displayed. And on repairing that file, it works fine. But I can't understand that where I'm making mistake in script. If anyone can solve this problem either by using PHPExcel (less execution time) or by solving error of corrupt file, then answer will be appreciated. Here is my code (CakePHP 3).
Input Array like
// Do not confuse with { instead of [. It's okey.
// $export_data and $data both are same (Input array).
{
"0": {
"customer_id": 1,
"name": "John Stevens",
"Date of 1 Purchase": "2014-08-05T00:00:00+0000",
"Date of 2 Purchase": "2014-09-05T00:00:00+0000",
"Date of 3 Purchase": "2014-10-05T00:00:00+0000",
...
...
... 350 Cols ...
}
"1": {
...
}
...
...
"999 Rows"
}
Using PHPExcel
$r = 1;
$filename = FILE_PATH . 'galliyan.xlsx';
$header = array_keys($export_data[0]);
$objPHPExcel = new \PHPExcel();
$col = 0;
foreach ($header as $field) {
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, 1, $field);
$col++;
}
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save($filename);
chmod($filename, 0777);
$r++;
$objPHPExcel = \PHPExcel_IOFactory::load($filename);
foreach($export_data as $row) {
$col = 0;
foreach ($row as $ro) {
$objPHPExcel->getActiveSheet()->setCellvalueByColumnAndRow($col, $r, $ro);
$col++;
}
$r++;
}
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save($filename);
chmod($filename, 0777);
EDIT (UPDATED CODE)
$filename = FILE_PATH . 'galliyan.xlsx';
$header = array_keys($export_data[0]);
$objPHPExcel = new \PHPExcel();
$sheet = $objPHPExcel->getActiveSheet();
$col = 0;
foreach ($header as $field) {
$sheet->setCellValueByColumnAndRow($col, 1, $field);
$col++;
}
$objPHPExcel->getActiveSheet()->fromArray($export_data, null, 'A2');
$writer = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$writer->save($filename);
chmod($filename, 0777);
Using "\t"
foreach ($data as $row) {
if (!$flag) {
$header = array();
// display field/column names as first row
$header = array_keys($row);
$header = $this->setExcelHeaders($header);
$this->createExcelFile($dir_name, $filename, $header, $export_type);
$flag = TRUE;
}
array_walk($row, array($this, 'cleanData'));
array_push($values, $row);
}
$values = $this->setValues($values);
$this->writeExcelFile($dir_name, $filename, $values);
function setExcelHeaders($hdrs) {
$header = '';
foreach ($hdrs as $title_val) {
$header .= $title_val . "\t";
}
return $header;
}
function createExcelFile($dir_name, $filename, $header, $export_type = '') {
$fp = fopen($dir_name . "/" . $filename, 'w');
fwrite($fp, "$header\n");
fclose($fp);
$permission = Configure::read('Config.PERMISSION');
if ($export_type == "") {
chmod($dir_name, $permission);
}
chmod($dir_name . "/" . $filename, $permission);
}
public function cleanData(&$str) {
$str = preg_replace("/\t/", "\\t", $str);
$str = preg_replace("/\r?\n/", "\\n", $str);
if (strstr($str, '"'))
$str = '"' . str_replace('"', '""', $str) . '"';
}
private function setValues($all_vals) {
$data = '';
for ($i = 0; $i < count($all_vals); $i++) {
$line = '';
foreach ($all_vals[$i] as $value) {
if ((!isset($value)) || ( $value == "")) {
$value = "\t";
}
else {
$value = str_replace('"', '""', $value);
$value = '"' . $value . '"' . "\t";
}
$line .= $value;
}
$data .= trim($line) . "\n";
}
return $values = str_replace("\r", "", $data);
}
function writeExcelFile($dir_name, $filename, $data) {
$fp = fopen($dir_name . "/" . $filename, 'a');
fwrite($fp, "$data");
fclose($fp);
}
As you mentioned "without PHPExcel", have you tried looking at alternatives that can be faster than PHPExcel? For instance, you can generate a 350x1000 XLSX spreadsheet with Spout (https://github.com/box/spout) in just a few seconds.
Generating a CSV file is also a good alternative and I'd recommend you going this route if you can. The export process will be way faster! But don't try to reinvent the wheel, there a already a lot of CSV writer out there, ready to use (Spout and PHPExcel both have one for instance).

take special lines from txt database PHP

I have text database
0,Apple,Green
1,Banana,Yellow
2,Cherry,Red
and when I call getdata.php?row=2 I need get data which is 2,cherry,red
I am a bachelor in PHP and I have only one example ,
please help me for this problem.
thanks
$file_handle = fopen("./news.txt", "rb");
while (!feof($file_handle) ) {
$line_of_text = fgets($file_handle);
$parts = explode(',', $line_of_text);
print $parts[0] . $parts[1] . $parts[2];
}
fclose($file_handle);
This would work and would also stop reading as soon as it found the right line (unlike the other answers who read the whole no file matter what)
if (isset($_GET['row']))
{
$file_handle = fopen("./news.txt", "rb");
$i = 0;
while (!feof($file_handle))
{
if ($i == $_GET['row'])
{
$line_of_text = fgets($file_handle);
$parts = explode(',', $line_of_text);
print $parts[0] . $parts[1] . $parts[2];
break;
}
$i++;
}
fclose($file_handle);
}
You first have to explode by rule with explode("/n", $txt) than you've an array of each rule. After you stored this explode in to a variable than you should explode a specific value again by ,.
A straightforward way to do this: if record number 2 is always on line number 3.
if (!isset($_GET['row']) || !is_int($_GET['row'])) {
echo "please supply a row number";
die;
}
$lines = file('news.txt');
// assumes record number 2 is on line 3
$row = $_GET['row'] + 1;
$parts = explode(',', $lines[$row]);
print $parts[0] . $parts[1] . $parts[2];
If record number 2 is not guaranteed to be on line 3
$row = $_GET['row'];
foreach ($lines as $line) {
if (strpos($line, $row) === 0) {
$parts = explode(',', $lines[$row]);
print $parts[0] . $parts[1] . $parts[2];
break;
}
}
If the file is extremely large you will want to read line by line from a buffer.
$row = $_GET['row'];
if ($fp = fopen('news.txt', 'r')) {
while ($line = fgets($fp)) {
if (strpos($line, $row) === 0) {
$parts = explode(',', $line);
print $parts[0] . $parts[1] . $parts[2];
break;
}
}
fclose($fp);
}

How to get a recuring parts from a file in php

I have a file file.txt. This file has portions and parts that recur throughout the file. I
am trying to read the parts between the last and the first key words.
I have managed to get the first and the last key words but I can't read the lines between the key words.
Here is my script
$file=file('file.txt');
$begin = 'first_line';
$end='last_line';
foreach ($file as $lineNumber => $line) {
$lineNumber++;
if (strpos($line,$begin))
{
echo $lineNumber.$line."<br/>";
}
elseif (strpos($line,$end))
{
echo $value."<br/>";
}
echo $lineNumber. $line."<br/>";
}
Please some one assist me.
Here you go:
$lines=file('data.txt');
$begin = 'first_line';
$end='last_line';
$switch = false;
$content = "";
foreach ($lines as $line_num => $line) {
if(strpos($line, $begin) !== false) {$switch = true;continue;}
if(strpos($line, $end) !== false) $switch = false;
if(!$switch) continue;
$content .= "Line #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n";
}
echo $content;
This will do it:
$file = file('file.txt');
$begin = 'first_line';
$end = 'last_line';
$isInside = false;
foreach ($file as $lineNumber => $line)
{
$lineNumber++;
if (!(strpos($line,$begin)===false))
$isInside = true;
if ($isInside)
echo $lineNumber." : ".$line."<br/>";
if (!(strpos($line,$end)===false))
$isInside = false;
}
Some points:
You were displaying everything regardless, my script only shows lines between $begin and $end.
Your comparison is case-sensitive
You had a major bug using strpos and assuming it returns true if it matches. It could also return 0 if the string matches at the beginning,hence using === to catch this. See the disclaimer on the strpos page.
$file=fopen("welcome.txt","r");
while(!feof($file))
{
$open=fgets($file);
print $open;
}
fclose($file);

Categories