Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Don't understand file manipulation to read and write to a "flat file" 1

Status
Not open for further replies.

wjgrayson

Technical User
Jun 1, 2004
75
0
0
US
I've created a test flat file called "users.dat". It has a three simple username password combinations separated by commas on three separate lines, like:
username1,password1
username2,password2
etc.

I've also created a simple php form to capture login in information. I'm having a terrible time figuring out how to use file manipulation to read the .dat file and authenticate the username passwords. For the purposes of my experiment, I'm not using any databases yet. My code for the authentication page looks something like this:

Code:
?php
$username = $_POST['username'];
$password = $_POST['password'];

$file = "users.dat";

$fp = fopen($file, "r");
while(!feof($fp)) {
	$data = fgets($fp, 1024);
}
if ((file_exists($username)) && (file_exists($username))){
echo "Thank you, $username for logging in.";
}
else {
echo "You will need to register."; 
}	
fclose($fp);

?>

So, I'm opening the file, keeping the file open to have it read until the end, then trying a simple if statement to test to see if the file is true. This is as far as I've gotten on my own. Any suggestions in the right direction?

Thanks in advance,
W!
 
Hi

wjgrayson said:
Any suggestions in the right direction?
Do not code your own login system at your current knowledge level. The result will probably be unstable or even vulnerable.
Code:
<?php
$username = $_POST['username'];
$password = $_POST['password'];

$file = "users.dat";

$ok = false;

$fp = fopen($file, "r");
while(!feof($fp)) {
  $data = fgets($fp, 1024);
  if (chop($data) == "$username,$password") {
    $ok = true;
    break;
  }
}
fclose($fp);

if ($ok) {
  echo "Thank you, $username for logging in.";
} else {
  echo "You will need to register.";
}

?>

Feherke.
 
While I agree with feherke, I'll take it this is a simple experiment, and not something that will be used in production.

With that said, I'd use the file() function instead of fopen, much more direct. But for the sake of argument, here's an example using your current fopen method

Basically you need to extract the file contents some way, fgets gets a line from the file every time its called. So you place it in a while loop to read the entire file.

Once the file is opened, and fgets has received a line of input, you can do what feherke suggest and check the entire line, or simply explode the line into its parts, and check each part individually. Basically what you want to do is get the information from the line, and use it in your comparisons.

Code:
while(!feof($fp)) {
  $data = fgets($fp, 1024);
$dataArray=explode(",",$data");
$userFromfile=$dataArray[0];
$passwordFromfile=$dataArray[1];

 if($userfromFile==$username && $passwordFromfile==$password){
 echo "Thank you for logging in";
 $logged=true;
 break;
 }  
}
if(!$logged{
echo "You will need to register.";
 }

Oh and by the way, checking if the file exists after having tried to open the file, is not very useful. You want to check if the file exists before trying to open it to avoid errors.

Code:
if(file_exists($file)){
$fp=fopen(...)
...
}

----------------------------------
Phil AKA Vacunita
----------------------------------
Ignorance is not necessarily Bliss, case in point:
Unknown has caused an Unknown Error on Unknown and must be shutdown to prevent damage to Unknown. 

Behind the Web, Tips and Tricks for Web Development. 
[URL unfurl="true"]http://behindtheweb.blogspot.com/[/URL]
 
To Vacunita and Feherke:
Thanks for your tips. And, this is an "experiment" of sorts -- I was investigating on my own some basic file manipulation principles. No way is this going into production!

What's (chopped(xxxxx))? No need to tell me. I will research on my own. The second solution makes a bit more sense to me because the .dat file is an array.
 
@Vacunita: Thanks again. And to reference your first reply, I did manage to crash Dreamweaver numerous times while running my experimental code through my local WAMP server. Yes. talk about an unstable coder :)
 
Hi

wjgrayson said:
The second solution makes a bit more sense to me because the .dat file is an array.
I just did it the easier way for the interpreter :
[ul]
[li]Joining is less expansive than splitting.[/li]
[li]One string comparison is less expansive than two.[/li]
[/ul]
It could be optimized even more :
Code:
$credentialline="$username,$password\n";
while(!feof($fp)) {
  $data = fgets($fp, 1024);
  if ($data == $credentialline) {
    $ok = true;
    break;
  }
}
But of course this has real benefits only on enormously big set of data :
Code:
[blue]master #[/blue] time php -r '$u="u"; $p="p"; $c="$u,$p\n"; $s="f,b\n";
 for ($i=0;$i<100000000;$i++) { $a=explode(",",$s); if ($a[0]==$u && $a[1]==$p) break; }'

real    1m42.002s
user    1m41.972s
sys     0m0.011s

[blue]master #[/blue] time php -r '$u="u"; $p="p"; $c="$u,$p\n"; $s="f,b\n"; for ($i=0;$i<100000000;$i++) if (chop($s)=="$u,$p") break;'

real    1m8.783s
user    1m8.759s
sys     0m0.013s

[blue]master #[/blue] time php -r '$u="u"; $p="p"; $c="$u,$p\n"; $s="f,b\n"; for ($i=0;$i<100000000;$i++) if ($s==$c) break;'

real    0m12.636s
user    0m12.622s
sys     0m0.011s
Taking in consideration that I often forget Donald Knuth's words...
Donald Knuth said:
Premature optimization is the root of all evil.
... better go with Phil's suggested code. With one thing to note : [tt]fgets()[/tt] returns the lines together with the end of line character(s), so you must handle them : either remove them ( [tt]chop()[/tt] in my first code ) or add them to the other side too ( [tt]\n[/tt] in my second code ).

( Note, if you not have Perl coding background, you may prefer [tt]rtrim()[/tt] instead of [tt]chop()[/tt]. )


Feherke.
 
Feherke --- It makes more sense now --- I'm more familiar with rtrim.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top