Forum Moderators: coopster

Message Too Old, No Replies

deleting from text files.

help please!

         

dreamcatcher

1:46 pm on Oct 25, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



hi guys,

I`ve written an upload script that lets people upload files to my server. The info gets stored in a text file, in the format:

date ¦ name ¦ email ¦ file ¦ size

This works fine. I`ve then done an admin page to show the info in a browser, which again works fine. I`ve popped a delete link next to each file in case I want to delete any. This uses the unlink() function and again works fine, whatever has been uploaded gets removed when the corresponding delete button is clicked. No probs so far.

The problem I have is that the info remains in the text file. I haven`t really worked with text files much before, so I was wondering how I remove the corresponding line from the text file as well as deleting the file? So it then disappears completely from the admin listing?

Thanks for the help!

:)

vincevincevince

3:11 pm on Oct 25, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



you'll be wanting to load it all into a variable, cutout he bit you don't want, and write to file again

dreamcatcher

4:36 pm on Oct 25, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks vincevincevince, I figured it was something along those lines. I haven`t worked with text files before so this is a new learning curve for me.

Would you know of a good tutorial that might help me out?

jatar_k

7:43 pm on Oct 25, 2003 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



I have this in one script

$fp = fopen($filename,"r+"); 
$counter = 0;
while($linetemp = fgetcsv($fp,10000,"¦")) {
if ($counter!= $rownum) {
$linearr[$counter] = $linetemp;
}
$counter++;
unset($linetemp);
}
fclose($fp);
$fp = fopen($filename,"w+");
$writestr = "";
foreach ($linearr as $whoknows) {
$writestr .= implode("¦",$whoknows) . "\n";
}
fwrite($fp,$writestr);
fclose($fp);

It gives the records a $rownum on output and then when you delete a line it passes that $rownum to this piece above and when the numbers match it just skips that record and then writes the file again with out it.

always replace broken pipes with "real" pipes

dreamcatcher

8:39 pm on Oct 25, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks for the code jatar_k, this has been driving me nuts. :) Its also been very interesting.

I`ve come up with the following which seems to work:

if ($action == "delete")

{

$contents = file($server_path . "log/uploads.log");

$before = $row-1;
$after = $row+1;

for($i = 0; $i < $before; $i++)

{

$remainder .= $contents[$i];

}

for($j = 0; $j > $after; $j++)

{

$remainder .= $contents[$j];

}

$fp = fopen($server_path . "log/temp.log", "ab");

if ($fp!= false)

{

fwrite($fp, $remainder);
fclose($fp);

}

@unlink($server_path . "log/uploads.log");
@rename($server_path . "log/temp.log", $server_path . "log/uploads.log");
@unlink($server_path . "uploads/" . $file);

fileDeleted();

}

The variable $row holds the row number and is passed in the url. I work out whats before that line and whats after it a la vincevincevince`s suggestion, then write to a new directory, delete the old and rename the new.

It seems to work fine, so I`m happy with that. If you think that I should include anything else, please let me know.

Thanks!

jatar_k

8:42 pm on Oct 25, 2003 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



if it works then you don't need to add anything, yet ;)

dreamcatcher

9:29 pm on Oct 25, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



cool. I`ve added your code to my code snippets file just in case.

:)

ergophobe

10:58 pm on Oct 25, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



dreamcatcher,

Since you know the row number and don't have to test each array element with a regex or something, here's a thoroughly untested idea that might work and saves a lot of looping. Note that I'm assuming that $row = the array index of that row, so row 1 is $row==0. Like I say, untested, including a high probability of unmatched parentheses, so you might get a parse error, but the idea should work. If you bite and give it a try, I'd love to hear back about how it went.

if ($action == "delete")
{
$contents = implode("\n", array_splice(file($path . "log/uploads.log"), $row, 1)); // comment 1

if ($fp = fopen($server_path . "log/temp.log", "ab")) // comment 2
{
fwrite($fp, $contents);
fclose($fp);

}

@unlink($server_path . "log/uploads.log");
@rename($server_path . "log/temp.log", $server_path . "log/uploads.log");
@unlink($server_path . "uploads/" . $file);

fileDeleted();

}
}

Comment 1

This is the equivalent of

$contents = file($server_path . "log/uploads.log"); //comment 1
$contents = array_splice($contents, $row, 1);
$contents = implode("\n", $contents);

Comment 2

All of these are functionally the same, the last is the most economical:

1.
$fp = fopen($server_path . "log/temp.log", "ab");
if ($fp!= false)

2.
$fp = fopen($server_path . "log/temp.log", "ab");
if ($fp == true)

3.
$fp = fopen($server_path . "log/temp.log", "ab");
if ($fp)

4.
if ($fp = fopen($server_path . "log/temp.log", "ab"));

Comment 3.


for($j = 0; $j > $after; $j++)
{
$remainder .= $contents[$j];
}

Yous say this works so I believe you. Maybe I'm just dense, but I can't figure out how. As I read it, it would fail the test on the first time through unless $after < 0 (i.e. $row is 0 in your example), in which case it runs as an infinite loop (or in this case stops when it addresses an array index out of range and everything crashes). Are you sure you aren't truncating your file at $row?

If you don't like my non-loop solution (or it doesn't work - I haven't tried it), I would do something like this

for ($j=$row; $j<count($contents); $j++)
{
$remainder .= $contents[$j];
}

Tom

dreamcatcher

11:10 pm on Oct 25, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



..and good job I did add your code because mine didn`t really work properly. Sigh... :(

I`ve added your code and it works great, just one thing. When I delete the last entry, I get the following message:

Warning: Invalid argument supplied for foreach() in /blah/blah/blah/admin.php on line 69

Any ideas?

dreamcatcher

11:12 pm on Oct 25, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks ergophobe, I guess you posted when I did. Like I mentioned, I`m not really up on text files, so I really don`t know what I`m doing. You probably noticed that. And yes, you were right, my code didn`t work.

If I can just figure out the error with the foreach loop, jatar_k`s example works just fine.

Thanks for the coding help.

:)

dreamcatcher

12:52 am on Oct 26, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Oh, I think I figured it out, just needed to test the state of the variable $linearr before the foreach loop. ie:

if (!empty($linearr))

{

foreach ($linearr as $whoknows)

{

$writestr .= implode("¦",$whoknows) . "\n";

}

}

Think thats ok. Seems to work fine. Thanks Jatar_k, you are a life saver.

:)

jatar_k

3:03 am on Oct 26, 2003 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



hehe
yeah, i forgot that piece of code did that, sry. I haven;t added that test to it yet but that is exactly the fix for it.

ergophobe

6:48 pm on Oct 28, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Oh well,

I guess I'll have to test that one myself.

Tom