Page 1 of 1

appending to a text file by reading to the end of it

Posted: Mon May 09, 2005 2:21 am
by permutations
I have a site where I'm using an .htpasswd file, but handling all the login elements manually. I create my own login dialog and read the .htpasswd file for authentication. Plus I let customers create their own accounts, and the script adds records to .htpasswd (not through Apache, but through PHP file functions).

I encountered a problem that's been driving me nuts because it was generating a 500 error on the Apache server, and when that happened I couldn't see any of my debugging code. I finally found a way around the problem, but I still don't understand why my initial approach didn't work, and I'd like to understand.

My script used this command to open the file:

Code: Select all

$fp = fopen( $filename, 'r+' );
I then read through the file in a loop, looking for a match between the entered username, and the username in the file. If I find one, then the user is updating his password. I update the record and all is well.

If the script does not find the username, then it's a new customer creating a record for the first time. I used this function to identify when I'd come to the EOF:

Code: Select all

feof( $fp );
When I read the EOF, I backed up the length of what I just read (my intent was to back up to before the EOF), and then tried to write the record. That ALWAYS resulted in a 500 error on Apache. The code looked like this:

Code: Select all

fseek( $fp, -1 * $len, SEEK_CUR );	// back up one record
				
if ( fwrite( $fp, "$user_to_match:$encrypted_password\n" ) === FALSE )
    DataError( "Could not write to password file.\r\n" );
					
if ( !fclose( $fp ) )
    DataError( "Could not close password file after writing.\r\n" );
Why does this not work????

Finally I changed it to this, and this works:

Code: Select all

if ( !fclose( $fp ) )
    DataError( "Could not close password file after writing.\r\n" ); 
			
$fp = fopen( $filename, 'a' );	// Open for appending, pointer at end of file.
if ( !$fp )
    DataError( "Could not open password file for appending.\r\n" );
		
if ( fwrite( $fp, "$user_to_match:$encrypted_password\n" ) === FALSE )
    DataError( "Could not write to password file.\r\n" );
				
if ( !fclose( $fp ) )
    DataError( "Could not close password file after writing.\r\n" );
Why must I close the file and reopen it to append before I can write to the bottom of the file. Why can't I open it for reading and writing, and simply navigate to the bottom of the file? What was causing the 500 error?

memory issue?

Posted: Mon May 09, 2005 9:33 am
by permutations
My Web host said that the 500 error on their Apache server is either due to a permissions problem (from suexec), or an attempt to use more memory than their server allows - 35MB. It couldn't be a permissions problem because I solved it without changing permissions, but I can't see where or how my program could possibly be using 35MB of memory. The file was tiny, and even if it wasn't, I was reading it one line at a time - not the whole thing at once.

Can someone confirm that my original code *SHOULD* have worked - that this syntax (using fopen with the "r+" option and navigating to the bottom by reading) is correct for writing a record to the end of the file? If so, then I'll see if I can find what's using up all that memory, but I don't want to go on a wild goose chase.

I want to understand the true cause of this problem and so I can find the best solution (and know why it works). These things always seem to come up again.

Thanks.