Bug fread in a txt file, read only one time - php

I'm creating a code to display the name of a server with enterprise rules, So for don't use Mysql i try a new things (for me) use php to read and rewrite files, that work perfectly for one part of my code and work perfectly but for the second he only read one time, and when i do a f5 the code don't increment.
He rewrite correctly because my file was at 000 and become 001
I try to use file() but he is disable since 7.0, try to use SplFileObject but it don't want to display anything and i don't like it because i understand nothing when i use it so i come back to fopen(),fread() and fwrite() and that don't work. I'm inPHP 7.3.1
The code that works :
<?php
if ( isset($_POST) AND !empty($_POST) ) {
$nom = "./config.txt";
$filez = fopen($nom, "r") or die("Unable to open file!");
$i = fread($filez,filesize($nom));
$year = getdate();
$idy = substr($year[year], 2);
$fichier = fopen("./resultsrv.txt", "w") or die("Unable to write file!");
for ($z; $z<$_POST['nbr']+1 ; $z++) {
$id = sprintf("%04d", $i+$z);
$nome = $_POST['type'].$_POST['OS'].$idy.$id."<br>" ;
echo $nome;
$nomewout = str_replace("<br>", ";", $nome);
fwrite($fichier,$nomewout);
}
$handle = fopen("./config.txt", "w") or die("Unable to write file!");
fwrite($handle,$id);
fclose($fichier);
fclose($handle);
}
?>
and the one that doesn't work because he doesn't increment :
<?php
if ( isset($_POST) AND !empty($_POST) ) {
$fileName = 'confchass.txt';
$read = fopen($fileName,"r");
$fn = fopen($fileName,"w+");
$i = fread($read,filesize($fileName));
$id = sprintf("%03d", $i+1);
echo "<div align='center'><h1>Le Chassis</h1>";
echo $_POST['Marque'].$_POST['DC'].$id;
echo "</div>";
fwrite($fn,$id);
fclose($read);
fclose($fn);
}
?>
I want he output a thing like XXXXXX001 and when i refresh or do a new POST from my forms he output XXXXXX002 and XXXXXX003 .... But he actualy output only XXXXXX001

The problem is that you open the file for reading and then for writing. But from the manual...
'w+' Open for reading and writing; place the file pointer at the
beginning of the file and truncate the file to zero length. If the
file does not exist, attempt to create it.
So this will blank out the file before you read the value from it.
To fix this (using your current method, you should read the value, then open it for writing and write the new value...
$read = fopen($fileName,"r");
$i = fread($read,filesize($fileName));
fclose($read);
$id = sprintf("%03d", $i+1);
echo "<div align='center'><h1>Le Chassis</h1>";
echo $id;
echo "</div>";
$fn = fopen($fileName,"w+");
fwrite($fn,$id);
fclose($fn);
You could shorten this by using file_get_contents() and file_put_contents().

Related

Checking if multiple files exsist if so create another

I'm having a problem trying to figure out a way to check for a file and if it exists check the next and so on.
I'm not familiar enough with loops so looking for help.
I'm putting together a small set of php forms to help me do rental inspections. The form will create a page for each area/item for the inspection with a photo and description of the problem if any. The form for the photo's is already working and not part of this.
I'm matching the paper form they will have me use. This could save me an hour or so on the windoze spreadsheet they would want me to put everything in and then print to PDF.
My laptop/PC is Linux. Would also save me having to get a Win machine or tablet.
I have everything else working. Just the page creation is giving me fits. I understand a loop should be the easiest to save having to write the file_exists search for each page up to 40 pages.
Here is a snip of were I'm at. The location this is sitting is not publicly accessible.
Thanks in advance
Bob
<?php
// This will be accessed for each area/item inspected
$dirpath = "/localhost/rent.inspect/";
// Get POST info from form page
$a1 = $_POST["a1"];
$a2 = $_POST["a2"];
$a3 = $_POST["a3"];
$a4 = $_POST["a4"];
…...
$a40 = &_POST[“a40”];
// File names we write to can be any name
$FileName1 = "$dirPath/page1.php";
$FileName2 = "$dirPath/page2.php";
$FileName3 = "$dirPath/page3.php";
$FileName4 = "$dirPath/page4.php";
…...
$FileName3 = "$dirPath/page39.php";
$FileName4 = "$dirPath/page40.php";
// Check if the first file is already created.
// If not create it and write, if is does exist check for the
// next file. Keep checking until one not created is found.
// Should never get to the 40th file at this time.
// Check if first file has already been created.
if(file_exists("$FileNam1"))
{
if(file_exists("$FileNam2"))
{
if(file_exists("$FileNam3"))
{
// Check for next one.... Should never see 40
// but keep checking to it just in case something is added
}
else
{
$myfile = fopen("$dirPath/$filename3", "w") or die("Unable to open file!");
$txt = "<font size=\"2\">$a1 $a2 $a3</font></b><br /><br />";
fwrite($myfile, $txt);
fclose($myfile);
}
}
else
{
$myfile = fopen("$dirPath/$filename2", "w") or die("Unable to open file!");
$txt = "<font size=\"2\">$a1 $a2 $a3</font></b><br /><br />";
fwrite($myfile, $txt);
fclose($myfile);
}
}
else
{
$myfile = fopen("$dirPath/$filename1", "w") or die("Unable to open file!");
$txt = "<font size=\"2\">$a1 $a2 $a3</font></b><br /><br />";
fwrite($myfile, $txt);
fclose($myfile);
}
?>
Several ways to do so, an easy one fitting your current problem could be :
for ($i = 1; $i < 41; ++$i) {
if (!file_exists($dirPath . '/page' . $i . '.php')) {
// fopen, fwrite, fclose ...
break;
}
}
You could also improve your variable initializations using an array to store your variables, even more when it's all about changing an increment integer.
Here is an example, not really useful, but explaining how you could do :
for ($i = 0; $i < 41; ++$i) {
$myVar['a' . $i] = $_POST['a' . $i];
}
you can check till the file exixts and increment the counter
$filepath = "/somepath/";
$filename = "FileNam"
$i=1;
$pathtocheck = $filepath + $filename + $i;
while ( file_exists ($pathtocheck ))
{
$i++
$pathtocheck = $filepath + $filename + $i;
}
// your code for file write will be here
// this code will check is there file exist if not while will break otherwise it will continue till no file like FileNam1 ,FileNam2 and so on ...

Odd Behavior when appending JSON file using PHP

So I have a JSON file containing basketball player information in the following format:
[{"name":"Lamar Patterson","team":1,"yearsLeft":0,"position":"PG","PPG":17},{"name":"Talib Zanna", "team":1,"yearsLeft":0,"position":"SF","PPG":13.1},....]
I want a user to be a able to add their own custom players to this file. To do this i try the following:
<?php
$json = file_get_contents('json/players.json');
$info = json_decode($json, true);
$info[] = array('name'=>$name, 'team'=>$team, 'yearsLeft'=>4, 'position'=>$position, 'PPG'=>$ppg);
file_put_contents('json/players.json', json_encode($info));
?>
This "sort of" works. But when I check the JSON file, I find that there are 3 new entries rather than 1:
{"name":"","team":null,"yearsLeft":4,"position":"","PPG":""},{"name":"","team":"3","yearsLeft":4,"position":"","PPG":""},{"name":"Jeff","team":null,"yearsLeft":4,"position":"C","PPG":"23"}
assuming $name="Jeff" $team=3 and $ppg=23 (populated via POST submission).
What's going on and how can I fix it?
You could try doing the following:
Untested code
<?php
if(!empty($name) && !empty($team) && !empty($position) && !empty($ppg)) {
$fh = fopen('json/players.json', 'r+') or die("can't open file");
$stat = fstat($fh);
ftruncate($fh, $stat['size']-1);//removes last ] char
fclose($fh);
$fh = fopen('json/players.json', 'a');
$info = array('name'=>$name, 'team'=>$team, 'yearsLeft'=>4, 'position'=>$position, 'PPG'=>$ppg);
fwrite($fh, ','.json_encode($info).']');
fclose($fh);
}
?>
This will append the only the new json to the file instead of opening the file, making php parse all the json and then writing it to the file again. In addition to that it will only store the data if the variables actually contain data.
Try this:
<?php
//get the posted values
$name = $_POST['name'];
$team = $_POST['team'];
$position = $_POST['position'];
$ppg = $_POST['ppg'];
//verify they're not empty
if(!empty($name) && !empty($team) && !empty($position) && !empty($ppg)) {
//Open the file
$fh = fopen('json/players.json', 'r+') or die("can't open file");
//get file info/stats
$stat = fstat($fh);
//final desired size after trimming the trailing ']'
$size = $stat['size']-1;
//file has contents? then remove the trailing ']'
if($size>0) ftruncate($fh, $size);
//close the current handle
fclose($fh);
// reopen the file for append
$fh = fopen('json/players.json', 'a');
//build your data array
$info = array('name'=>$name, 'team'=>$team, 'yearsLeft'=>4, 'position'=>$position, 'PPG'=>$ppg);
//if this is not the first item on file
if($size>0) fwrite($fh, ','.json_encode($info).']'); //append with comma
else fwrite($fh, '['.json_encode($info).']'); //first item on file
fclose($fh);
}
?>
Maybe your php config is not set to convert the post/get variables to global variables. This happened to me a couple of times so I rather create the variables I'm expecting from the post/get request. Also watch out for the page encoding, from personal experience you could be getting empty strings there.

PHP Write and Read from Text File

I have an issue with writing and reading to text file.
I have to first write from a text file to another text file some values which I need to read again. Below are the code snippets:
Write to text file:
$fp = #fopen ("text1.txt", "r");
$fh = #fopen("text2.txt", 'a+');
if ($fp) {
//for each line in file
while(!feof($fp)) {
//push lines into array
$thisline = fgets($fp);
$thisline1 = trim($thisline);
$stringData = $thisline1. "\r\n";
fwrite($fh, $stringData);
fwrite($fh, "test");
}
}
fclose($fp);
fclose($fh);
Read from the written textfile
$page = join("",file("text2.txt"));
$kw = explode("\n", $page);
for($i=0;$i<count($kw);$i++){
echo rtrim($kw[$i]);
}
But, if I am not mistaken due to the "/r/n" I used to insert the newline, when I am reading back, there are issues and I need to pass the read values from only the even lines to a function to perform other operations.
How do I resolve this issue? Basically, I need to write certain values to a textfile and then read only the values from the even lines.
I'm not sure whether you have issues with the even line numbers or with reading the file back in.
Here is the solution for the even line numbers.
$page = join("",file("text2.txt"));
$kw = explode("\n", $page);
for($i=0;$i<count($kw);$i++){
$myValue = rtrim($kw[$i]);
if(i % 2 == 0)
{
echo $myValue;
}
}

Manage several files in PHP

I'm testing php because I'm a freshman in this matter. I put my php code in a free server, they let me do my own index.php, manage some php variables (like register_globals, magic_quotes_gpc etc. I left them as default), but apparently I can handle not more than one file in a php code, for example:
<?php
//--------Updating Data-------------
$cdc = intval($_POST['cantidadDeCapitulos']);
$toWrite = array('ctot' => $cdc);
for($i=1;$i<$cdc+1;$i += 1){
$toWrite["cap".$i] = $_POST['numdeCap'.$i];
}//---------------------------------
$datos = file_get_contents("myfile.json.");
$toWrite = json_encode( $toWrite );
//Open a file in write mode
$fp = fopen("myfile2.json", "w");
if(fwrite($fp, "$toWrite")) {
echo "&verify=success&";
} else {
echo "&verify=fail&";
}
fclose($fp);
?>
If I comment out the line $datos = file_get_contents("myfile.json."); it's alright!, something is written in myfile2.json but if it is uncommented, the data is not updated. Both files have permission 666 and they are in the same directory i.e., /root.
$datos = file_get_contents("myfile.json.");
Seems like a typo has occurred. Take off the final dot from your file. I mean, change the line to:
$datos = file_get_contents("myfile.json");
try this:
<?php
$file = 'myfile.json';
// Open the file to get existing content
$current = file_get_contents($file);
// Write the contents back to the file
file_put_contents($file, $current);
?>

PHP: Read Specific Line From File

I'm trying to read a specific line from a text file using php.
Here's the text file:
foo
foo2
How would I get the content of the second line using php?
This returns the first line:
<?php
$myFile = "4-24-11.txt";
$fh = fopen($myFile, 'r');
$theData = fgets($fh);
fclose($fh);
echo $theData;
?>
..but I need the second.
Any help would be greatly appreciated
$myFile = "4-24-11.txt";
$lines = file($myFile);//file in to an array
echo $lines[1]; //line 2
file — Reads entire file into an array
omg I'm lacking 7 rep to make comments. This is #Raptor's & #Tomm's comment, since this question still shows up way high in google serps.
He's exactly right. For small files file($file); is perfectly fine. For large files it's total overkill b/c php arrays eat memory like crazy.
I just ran a tiny test with a *.csv with a file size of ~67mb (1,000,000 lines):
$t = -microtime(1);
$file = '../data/1000k.csv';
$lines = file($file);
echo $lines[999999]
."\n".(memory_get_peak_usage(1)/1024/1024)
."\n".($t+microtime(1));
//227.5
//0.22701287269592
//Process finished with exit code 0
And since noone mentioned it yet, I gave the SplFileObject a try, which I actually just recently discovered for myself.
$t = -microtime(1);
$file = '../data/1000k.csv';
$spl = new SplFileObject($file);
$spl->seek(999999);
echo $spl->current()
."\n".(memory_get_peak_usage(1)/1024/1024)
."\n".($t+microtime(1));
//0.5
//0.11500692367554
//Process finished with exit code 0
This was on my Win7 desktop so it's not representative for production environment, but still ... quite the difference.
If you wanted to do it that way...
$line = 0;
while (($buffer = fgets($fh)) !== FALSE) {
if ($line == 1) {
// This is the second line.
break;
}
$line++;
}
Alternatively, open it with file() and subscript the line with [1].
I would use the SplFileObject class...
$file = new SplFileObject("filename");
if (!$file->eof()) {
$file->seek($lineNumber);
$contents = $file->current(); // $contents would hold the data from line x
}
you can use the following to get all the lines in the file
$handle = #fopen('test.txt', "r");
if ($handle) {
while (!feof($handle)) {
$lines[] = fgets($handle, 4096);
}
fclose($handle);
}
print_r($lines);
and $lines[1] for your second line
$myFile = "4-21-11.txt";
$fh = fopen($myFile, 'r');
while(!feof($fh))
{
$data[] = fgets($fh);
//Do whatever you want with the data in here
//This feeds the file into an array line by line
}
fclose($fh);
This question is quite old by now, but for anyone dealing with very large files, here is a solution that does not involve reading every preceding line. This was also the only solution that worked in my case for a file with ~160 million lines.
<?php
function rand_line($fileName) {
do{
$fileSize=filesize($fileName);
$fp = fopen($fileName, 'r');
fseek($fp, rand(0, $fileSize));
$data = fread($fp, 4096); // assumes lines are < 4096 characters
fclose($fp);
$a = explode("\n",$data);
}while(count($a)<2);
return $a[1];
}
echo rand_line("file.txt"); // change file name
?>
It works by opening the file without reading anything, then moving the pointer instantly to a random position, reading up to 4096 characters from that point, then grabbing the first complete line from that data.
If you use PHP on Linux, you may try the following to read text for example between 74th and 159th lines:
$text = shell_exec("sed -n '74,159p' path/to/file.log");
This solution is good if your file is large.
You have to loop the file till end of file.
while(!feof($file))
{
echo fgets($file). "<br />";
}
fclose($file);
Use stream_get_line: stream_get_line — Gets line from stream resource up to a given delimiter
Source: http://php.net/manual/en/function.stream-get-line.php
You could try looping until the line you want, not the EOF, and resetting the variable to the line each time (not adding to it). In your case, the 2nd line is the EOF. (A for loop is probably more appropriate in my code below).
This way the entire file is not in the memory; the drawback is it takes time to go through the file up to the point you want.
<?php
$myFile = "4-24-11.txt";
$fh = fopen($myFile, 'r');
$i = 0;
while ($i < 2)
{
$theData = fgets($fh);
$i++
}
fclose($fh);
echo $theData;
?>
I like daggett answer but there is another solution you can get try if your file is not big enough.
$file = __FILE__; // Let's take the current file just as an example.
$start_line = __LINE__ -1; // The same with the line what we look for. Take the line number where $line variable is declared as the start.
$lines_to_display = 5; // The number of lines to display. Displays only the $start_line if set to 1. If $lines_to_display argument is omitted displays all lines starting from the $start_line.
echo implode('', array_slice(file($file), $start_line, lines_to_display));
I searched for a one line solution to read specific line from a file.
Here my solution:
echo file('dayInt.txt')[1]

Categories