I want to be able to +1 to $i every page reload.
I have come across a very simple issue, that I am struggling to find a solution online.
Heres my code:
$backupNumber = fopen("$v", "r+") or die("Unable to open file!");
$i = fread($backupNumber,filesize("invoices/invoice1/backupN.txt"));
$i = intval($i);
$i = $i + 1;
echo $i;
fwrite($backupNumber,$i);
$a = "invoices/" . $invoiceN . "/backup" . $i;
fclose($backupNumber);
and in the txt file is simply the number '1' to start off with.
The issue occurs when reloading the page when I echo $i it outputs:
2 then 13 then 1214 then 12131215 then 2147483648 etc.
I want it to simple output
2 then 3 then 4 etc
You append the text file, that is why this is happening.
My advice is to use file_get_contents and file_put_contents.
$i = file_get_contents("invoices/invoice1/backupN.txt");
$i++;
Echo $i;
file_put_contents("invoices/invoice1/backupN.txt" $i);
File get and put contents always reads the whole text file.
I don't think you need to intcast the string, it should work without it.
The code can be a one liner too. It's messy but compact.
file_put_contents("invoices/invoice1/backupN.txt", file_get_contents("invoices/invoice1/backupN.txt")+1);
After reading the number from the file, the handle is positioned at its end, so while your math is sound, you're appending the new number to the file instead of overwriting it.
One approach to handle this is to reset the handle use fseek before writing:
fseek($backupNumber, 0);
fwrite($backupNumber, $i);
You are appending the file thats why this is happening. Instead of using r+ mode just use w+ mode.
r+ mode only opens a file and allow you to read and write but dont over write the content.
Where as in w+ mode always a new empty file is created.
Do something like
$backupNumber = fopen("$v", "r+") or die("Unable to open file!");
$i = fread($backupNumber,filesize("invoices/invoice1/backupN.txt"));
fclose($backupNumber);
$backupNumber = fopen("$v", "w+") or die("Unable to open file!");
$i = intval($i);
$i = $i + 1;
echo $i;
fwrite($backupNumber,$i);
$a = "invoices/" . $invoiceN . "/backup" . $i; fclose($backupNumber);
Else you can also you fseek() to point at 0th location in file and override the content in file.
Another variation on a theme perhaps...
function updatecount(){
$file='invoices/invoice1/backupN.txt';
if( !realpath( $file ) )$i=0;
$i=intval( trim( file_get_contents( $file ) ) ) + 1;
file_put_contents( $file, $i );
return $i;
}
$count=updatecount();
echo strval( $count );
Related
I am trying to delete items inside List A from list B
And the two inside a text file
Example : a.txt
1
3
6
b.txt
2
3
6
I tried more than one method previously but with large files it does not work as it should
$a = file('a.txt', FILE_IGNORE_NEW_LINES);
$b = file('b.txt', FILE_IGNORE_NEW_LINES);
$n = 'new.txt';
for ($i = 0;$i < count($b);$i++)
{
if (!in_array($b[$i], $a))
{
$c = file_get_contents($n);
$c .= $b[$i] . "\n";
file_put_contents($n, $c);
}
}
Is there a better way to handle large files like 80k line?
This code mainly changes the way the files are read and written, so that the second file is read 1 line at a time and not read all in memory. The output also uses FILE_APPEND in file_put_contents() so that it doesn't need to read the file again.
The first part is to create an array of the a.txt file, with the value as the index to allow you to use isset() rather than in_array() which will make the searching a lot quicker.
Then read the second file 1 line at a time, check if it's present and add the data if needed...
$fileA = fopen('a.txt', 'r');
$a = [];
while($entry = fgets($fileA))
{
$a[trim($entry)] = true;
}
$fileB = fopen('b.txt', 'r');
$n = 'new.txt';
// Clear the file
file_put_contents($n, '');
while($b = fgets($fileB))
{
if (!isset($a[trim($b)]))
{
file_put_contents($n, $b, FILE_APPEND);
}
}
My PHP code is generating 495 HTML pages from 495 txt files and working correctly. But right now, I'm trying to change it as a way to change the value of title tag dynamically; so I'm trying to replace %TITLE% with $Oneline that is the first line of each txt pages.
I have tried many syntaxes such as prg_replace, str_replace and much more all seems unsuccessful. In fact those lines of codes change nothing on my HTML pages.
To be more clear:
Trying to replace %TITLE% with $Oneline.
$Oneline is the first line of the txt file.
Thanks for any help.
<?php
for ($i = 1; $i <= 495; $i++)
{$j = 1;
$SousrceFile = #fopen($SousrceFile, 'r') ;
$TargetFile = fopen($TargetFile, 'w+') ;
fwrite($TargetFile, "<title>%TITLE%</title>\n");
while ($Oneline = #fgets($SousrceFile, 4096))
{$j = $j + 1;
if (strlen($Oneline) !==0)
{
$title = $Oneline;
$newTitle = preg_replace('%TITLE%', $title, $newTitle,1 );
...?>
Please take a look at preg_replace(), the parameters are
preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
In your code you are using the variable $title to replace the pattern in $newTitle with a limit of one. I think you want to replace the text in the target file instead.
Update:
There are two solutions that come into my mind right now:
Instead of writing your text into the file directly, write it into
a variable instead. This variable can be searched by
preg_replace() and you can change your title dynamically. After
you done that, write the variable into the targe file by e.g.
fputs().
Instead of replacing the title, set the title directly where it is needed, when you are writing the header section. Than there is no need for replacing.
I would recommend solution one. You know how to do that?
As far as I can see, $newTitle is not defined prior to pre_replace.
After I couldn't solve the problem, I moved the retreiving data loop to above of the title and as Aaron suggested at this post It made it quiet simple as bellow:
<?php
for ($i = 1; $i <= 495; $i++)
{$j = 1;
$SousrceFile = #fopen($SousrceFile, 'r');
$TargetFile = fopen($TargetFile, 'w+');
while ($Oneline = #fgets($SousrceFile, 4096))
{$j = $j + 1;
if (strlen($Oneline) !==0)
$title = $Oneline;
fwrite($TargetFile, "<title>{$title}</title>\n");
...?>
I have 1600 images, each 256px. These images have been sliced in photoshop from an image that is 10240px x 10240px in to the tiles. Problem is, photoshop has named them image_0001.png, image_0002.png...
I would like to rename these in to a usable file name such as image_x_y.png x being tile number in that row, y being tile number in that column...
And ideas how i can automate the renaming of these, or if not how i can pass these images through php, so that i can access image.php?x=2&y=1 ect...
thanks in advance
EDIT:
I have no permission to answer my own question but, used this as renaming would be required on every update. Not ideal...
<?php
$x=$_GET['x'];
$y=$_GET['y'];
$image=(($y-1)*40)+$x;
if ($image<10){
$image="0".$image;
}
$url="tiles/" . $image . ".jpg";
header("Location:" . $url);
?>
You could open the directory containing your files and then create a loop to access all images and rename them, like:
<?php
if ($handle = opendir('/path/to/image/directory')) {
while (false !== ($fileName = readdir($handle))) {
//do the renaming here
//$newName =
rename($fileName, $newName);
}
closedir($handle);
}
?>
Useful functions:
rename(),readdir(), readdir(), str_replace(), preg_replace()
Hope this helps!
You don't have to rename them, just calculate the "linear id" on every access.
so, assuming you have a 40 * 40 set of files, in image.php you'd have something like
$fileid = $x * 40 + y;
$filename = sprintf("image_%04d.png",$fileid);
// send the file with name $filename
What formula you need depends on how it was sliced, could as well be $y * 40 + x
The main advantage is that should your image be updated, it will be ready to use without the intermediate step of renaming the files.
Try this :
$dir = "your_dir";
$i = 0;
$j = 0;
$col = 5;
foreach(glob($dir . '/*') as $file)
{
rename($file, "image"."_".$j."_".$i);
$i++;
if($i % $col == 0)
{
$j++;
}
}
If you know for sure that the routine that converted your files always named the resulting images in the same order
i.e. top left = 0001 ...... Bottom right = 0016
Then it should be fairly simple to write a quick CLI script to go through and rename all your images.
Alternatively if you are going to use that same image converter again many times it may be simpler to make your image.php?x=1&y=2 script workout what file to serve then you wont need to do the renaming every time you get new images.
-read the soure folder with your images (http://php.net/manual/de/function.readdir.php)
-put the part of each imagename between "_" and "."
-parse it ($image_nr) as integer
-do the following:
$y = floor($image_nr/40);
$x = $image_nr%40;
finaly put each image in your destination directory with the new name
I Have not tested it but you could try using this:
$imagesInARow = 10240/256; //=> 40
$rows = 1600 / $imagesInARow; //=> 40
$imageIndex = 1;
for($i = 1; $i <= $rows; $i++) { // row iteration
for($j = 1; $j <= $imagesInARow; $j++) { // columns iteration
rename('image_'. str_pad($imageIndex, 4, '0', STR_PAD_LEFT).'.png',
"image_{$i}_{$j}.png");
$imageIndex ++;
}
}
Thank you for taking the time to read this and I will appreciate every single response no mater the quality of content. :)
Using PHP, I'm trying to get the last 15 lines of a text document (.txt) and store that data into a php variable. I understand that this is possible, however when I do get the last 15 lines, is it possible to retain the order? For example:
text document:
A
B
C
When I grab the text document from the last 15 characters, I don't want the echo to end up like:
C
B
A
All assistance is appreciated and I look forward to your replies; thank you. :) If I didn't explain anything clearly and/or you'd like me to explain in more detail, please reply. :)
Thank you.
Try using array_slice, which will return a part of an array. In this case you want it to return the last 15 lines of the array, so:
$filearray = file("filename");
$lastfifteenlines = array_slice($filearray,-15);
If you don't mind loading the entire file into memory:
$lines = array_slice(file('test.txt'), -15);
print_r($lines );
If the file is too large to fit into memory you can use a circular method:
// Read the last $num lines from stream $fp
function read_last_lines($fp, $num)
{
$idx = 0;
$lines = array();
while(($line = fgets($fp)))
{
$lines[$idx] = $line;
$idx = ($idx + 1) % $num;
}
$p1 = array_slice($lines, $idx);
$p2 = array_slice($lines, 0, $idx);
$ordered_lines = array_merge($p1, $p2);
return $ordered_lines;
}
// Open the file and read the last 15 lines
$fp = fopen('test.txt', 'r');
$lines = read_last_lines($fp, 15);
fclose($fp);
// Output array
print_r($lines);
This method will also work if the file has less than 15 lines- returning an array with however many lines are in the file.
You can use fseek with a negative position to seek backwards through the file, counting newlines as you go.
I'm too tired to write up copy/past-able code, but there are some examples in the comments to the manual page for fseek that are very close to what you want.
If the file isn't bigger than available memory you can do this:
$fArray = file("filename");
$len = sizeof($fArray);
for($i=$len -15;$i<$len ;$i++)
{
echo $fArray[$i];
}
If you have a file that is hundreds of megabytes :
$rc = fopen("file","r");
for ($i=0; $line = fgets($file) ;$i++)
{
if ($i%15 == 0)
{
$last15 = array();
}
$last15[] = $line;
}
echo join("\n",$last15);
the longer array solution:
array_slice(explode("\n",file_get_contents($file)),-15);
the shorter array solution:
array_slice(file($file),-15);
This code will open the file, show the total lines, show the header of file and show the last lines of file defined in $limit.
<?php
// open the file in read mode
$file = new SplFileObject('file.csv', 'r');
// get the total lines
$file->seek(PHP_INT_MAX);
$last_line = $file->key();
echo $last_line;
echo "<br>";
// Rewind to first line to get header
$file->rewind();
// Output first line if you need use the header to make something
echo $file->current();
echo "<br>";
// selecting the limit
$limit = 6;
// selecting the last lines using the $limit
$lines = new LimitIterator($file, $last_line - $limit, $last_line);
//print all the last 6 lines array
//print_r(iterator_to_array($lines));
//echo "<br>";
// Loop over whole file to use a single line
foreach ($lines as $line) {
print_r($line);
echo "<br>";
}
I'm trying to process a for loop within a for loop, and just a little wary of the syntax... Will this work? Essentially, I want to run code for every 1,000 records while the count is equal to or less than the $count... Will the syntax below work, or is there a better way?
for($x = 0; $x <= 700000; $x++) {
for($i = 0; $i <= 1000; $i++) {
//run the code
}
}
The syntax you have will work, but I don't think it's going to do exactly what you want. Right now, it's going to do the outer loop 700,001 times, and for every single one of those 700,001 times, it's going to do the inner loop.
That means, in total, the inner loop is going to run 700,001 x 1001 = about 700.7 million times.
If this isn't what you want, can you give a bit more information? I can't really work out what "I want to run code for every 1,000 records while the count is equal to or less than the $count" means. I don't see any variable named $count at all.
Well, essentially, I'm reading in a text file and inserting each of the lines into a db. I did originally try while(!feof($f)) [where $f = filename], but it keeps complaining of a broken pipe. I thought this would be another way to go
$f should be file-handle returned by fopen(), not a filename.
$file_handle = fopen($filename, 'r');
while(!feof($file_handle)) {
$line = fgets($file_handle);
$line = trim($line); // remove space chars at beginning and end
if(!$line) continue; // we don't need empty lines
mysql_query('INSERT INTO table (column) '
.'VALUES ("'.mysql_real_escape_string($line).'")');
}
Read through the documentation at php.net for fopen(), fgets(). You might also need explode() if you need to split your string.
If your file isn't big, you might want to read it into an array at once like this:
$filelines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach($filelines as $line) {
do_stuff_with($line);
}
Hmm. Ok... Well, essentially, I'm reading in a text file and inserting each of the lines into a db. I did originally try while(!feof($f)) [where $f = filename], but it keeps complaining of a broken pipe. I thought this would be another way to go..
To read a text file line by line I usually:
$file = file("path to file")
foreach($file as $line){
//insert $line into db
}
Strictly answering the question, you'd want something more like this:
// $x would be 0, then 1000, then 2000, then 3000
for($x = 0; $x < 700000; $x += 1000) {
// $i would be $x through $x + 999
for($i = $x; $i < $x + 1000; $i++) {
//run the code
}
}
However, you should really consider one of the other methods for importing files to a database.