Jump to content

Class Work Help (Prof Is Mia)


Jptalon

Recommended Posts

Hello all,

New here and in need of a little help, as the title states my Professor is MIA. I take online classes so our only contact is through emails. Anyhow, here is my issue. He instructed me to create a function to validate an email and password. Easy enough, but this function needs do one or the other as it is called to do. 3 pages, 1 is the form with HTML only, 2nd is processing page that calls validate function, 3rd is the function. As of right now it will not decide which to do and does both twice, hence my problem. I have read everywhere and everything i can, and have not found how to do this. I could do it a different way but then it would not be as he required.

 

<?php
include ('homepage/library.php');
$email = $_POST['email'];
$password = $_POST['password'];
validate($email, 1);
if (false) {
setcookie('error', 'Invalid email or password', 0);
echo $_COOKIE['error'];
}
validate($password, 2);
if (false) {
setcookie('error', 'Invalid email or password', 0);
echo $_COOKIE['error'];
}
?>

 

I believe on this one below that $email = $_POST['email']; and $password = $_POST['password']; are going around the purpose as how they are called in the top is suppose to pass the information. But it is not passing it to the function. Yet the info is there as i can echo it before the function. Any help please.....

 

<?php
function validate() {
if (1) {
 $email = $_POST['email'];
 if (!preg_match('^[a-zA-Z0-9_\-\.]+@[a-zA-z0-9\-]+\.[a-zA-Z0-9\-\.]+$^', $email)){
  echo '<h2>Email is Invalid</h2>';
  return false;
 }else{
 echo '<h2>Email is Valid</h2>';
 }

}
if (2){
 $password = $_POST['password'];
 if (!preg_match("/^.*(?=.{8})(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).*$/", $password)){
 echo '<h2>Password is Invalid</h2>';
 return false;
 }else{	 
   echo '<h2>Password is Valid</h2>';
  }
  return true;
}
}
?>

Link to comment
Share on other sites

So, you have the right idea in sending it a second argument. But 1. It should make sense (not 1 or 2 but 'email' or 'password'), and 2. if(1) will always == true, and if(2) will always == true. You need to capture the arguments you're passing to your function.

function validate($string_to_validate, $type_of_validation){
  switch($type_of_validation){
     case 'email':
        .... etc your code

Link to comment
Share on other sites

Also, don't echo "so and so is Invalid" in your function. Outputting stuff is going beyond the responsibility of the function. Just return true or false, and then you can use that return value to output something.

 

if (validate($email, 'email')) {
    echo 'Email is good!';
} else {
    echo 'Email is invalid!';
}

Link to comment
Share on other sites

Well now that makes some sense lol and I was questioning if 1 & 2 were always true. Lets see if i can get this done now. This is only a 3rd of whats needed

validate($email, 1);
validate($password, 2);

This bit of code was actually give to me by my Professor, hence the 1 & 2. This is what will now become $type_of_validation correct?

Link to comment
Share on other sites

I personally would use the strings and tell the teacher than since 1 and 2 are meaningless, you used arguments that made sense. I would also tell him if he's not interested in teaching, you'll continue to follow advice given to you by seasoned professionals. But I'm a bit of a hardass on bad teachers. I had too many of them.

 

And yes, either 1,2 or 'email','password' is what will be saved as $type_of_validation.

Link to comment
Share on other sites

Also, don't echo "so and so is Invalid" in your function. Outputting stuff is going beyond the responsibility of the function. Just return true or false, and then you can use that return value to output something.

I agree, I was just doing that for testing purposes. They are not actually needed. In the end if either one fails to validate then I will have the 2nd page set a cookie and send the user back to the form. Then display the cookie error message.

 

Thanks to the both of you for your help

Link to comment
Share on other sites

I personally would use the strings and tell the teacher than since 1 and 2 are meaningless, you used arguments that made sense. I would also tell him if he's not interested in teaching, you'll continue to follow advice given to you by seasoned professionals. But I'm a bit of a hardass on bad teachers. I had too many of them.

 

And yes, either 1,2 or 'email','password' is what will be saved as $type_of_validation.

 

Thanks again. I have great grades so far in this class. That is the least of my worries. I actually need to know how and why with this php class. Not just pass the class. I also have only had 3 emails from him all semester so far, then worst off is I don't even get my past work corrected. Only graded, so I cant learn from that. grrrr

Link to comment
Share on other sites

Go to the administration then. Don't be a victim.

 

The manual is a good resource. If you don't understand why you have to do function validate($string_to_validate, $type_of_validation){ instead of function validate(), read the manual section on functions.

Link to comment
Share on other sites

In addition to the advice above, you should never ever restrict the passwords as you've done above. A password should only be validated against the password provided by the user at sign up. Putting such artificial limits on a password is counter-productive, as you make it a lot easier to crack the passwords.

 

Also, I'd make two different functions, if you have two different types of inputs to validate.

Link to comment
Share on other sites

validate($email, 1);
if (false) {
setcookie('error', 'Invalid email or password', 0);
echo $_COOKIE['error'];
}

 

Also, if (false) will always be false. It looks like the validate function should be returning TRUE or FALSE. Then you capture the return value and process accordingly:

 

$rtc = validate($email, 1);
if (! $rtc) {
 setcookie('error', 'Invalid email or password', 0);
 echo $_COOKIE['error'];
}

 

Jessica is correct in saying that the parameter should make sense. But I would use defined constants for it:

 

define('C_VALIDATE_EMAIL', 1);
define('C_VALIDATE_PASSWORD', 2);

$rtc = validate($email, C_VALIDATE_EMAIL);

## And then in the function
 switch($type_of_validation){
   case C_VALIDATE_EMAIL:
   ## ...

 

It's a matter of personal preference, but it prevents the problem of mistyping the string (spelling or case) in some place and then wondering why it does not work. If you spell the constant wrong, PHP will issue a warning.

 

You are developing with error reporting on, right?

Link to comment
Share on other sites

In addition to the advice above, you should never ever restrict the passwords as you've done above. A password should only be validated against the password provided by the user at sign up. Putting such artificial limits on a password is counter-productive, as you make it a lot easier to crack the passwords.

 

Also, I'd make two different functions, if you have two different types of inputs to validate.

I agree with your advice too, but this is class work and he is very specific on requirements. I also thought it was strange on his very strict validating on passwords. I didnt even fully follow it cause I had bigger things to worry about. Along with a digit and a capital, it was exactly 8 long and not all capitals. Seeing as this maybe gets me a third of the way through the assignment i decided not to over think that part. Now I do need to check against current users and such.

 

Side note, the above help was awesome and worked perfectly, with hitting the point of making me understand. Sometimes "Manual" site is like greek lol

Link to comment
Share on other sites

You are developing with error reporting on, right?

Yes of course, that's possibly the main reason i have made it this far with an MIA professor. Though I do think i read the server can be set to not report, but I wouldn't know anything about that. I do know i can code to report differently. I wont be doing that.

 

Currently now I am up to this point, and it's working as required. I had to take off for half the day for an appointment.

 

<?php
include ('/homepage/library.php');
$email = $_POST['email'];
$password = $_POST['password'];
if (validate($email, 1)) {
echo '<h2>Email is Valid</h2>';
}
if (validate($password, 2)) {
echo '<h2>Password is Valid</h2>';
}else{
setcookie('error', 'Invalid email or password', 0);
Header ('Location: http://---/---/assignment3/assignment3.php');
echo $_COOKIE['error'];
}
?>

<?php
function validate($string_to_validate, $type_of_validation){
switch($type_of_validation){
case '1':
$email = $_POST['email'];
if (!preg_match('^[a-zA-Z0-9_\-\.]+@[a-zA-z0-9\-]+\.[a-zA-Z0-9\-\.]+$^', $email)){
return false;
}else{
return true;
}
case '2':
$password = $_POST['password'];
if (!preg_match("/^.*(?=.{8})(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).*$/", $password)){
return false;
}else{	
 return true;
}
}
}
function checkLogin ()
//just started this part.
?>

Edited by Jptalon
Link to comment
Share on other sites

if (!preg_match('^[a-zA-Z0-9_\-\.]+@[a-zA-z0-9\-]+\.[a-zA-Z0-9\-\.]+$^', $email)){
return false;
}else{
return true;
}

 

return !! preg_match('^[a-zA-Z0-9_\-\.]+@[a-zA-z0-9\-]+\.[a-zA-Z0-9\-\.]+$^', $email);

 

Same thing, shorter. It even works without the !! but just in case you really needed a boolean.

 

case '1':

 

There is no need for the extra ' case 1: works just the same.

Edited by ignace
Link to comment
Share on other sites

I'd use return (bool) preg... instead, if a proper boolean is required. Less magic, and a lot easier to read. ;)

 

As for header ('Location:') calls: It's quite pointless to echo something to the browser after it, as the browser will immediately discard all content and display the new URL afterwards. I'd also move the call to the success block, as you don't really need to show the form anew once you're logged in (or registered). It'll also prevent the F5-resend problem that will occur otherwise, with most browsers.

If the validation fails, show the form anew with the error message and the user-submitted details already present. That is, everything except for the value of the type="password" fields. Your users will thank you for it. This means that there is no need to set a cookie on failure, but do make sure you regenerate the session ID upon a successful login.

 

Lastly, assigning content from the $_POST array into variables of their own, only to send those variables to a function for validation, is wasteful. I'd skip the variable, and use the value from the $_POST array directly. Only when I know that the data is clean would I assign it to a variable for further processing.

 

Another "trick" I'm fond of using, is to test for error conditions, not successes. That way, if I detect an error I can deal with it immediately. Often by triggering an error/warning message, and exiting early. For validation you'll want to make sure that you've validated all of the user-submitted data, before you trigger the error and halt the script; Nothing is more annoying than to fix a 40-element form with one submission per input field, only because the author was lazy/ignorant. Better to show all of the failures in one go, so that it can be corrected all in one go.

Doing it like that, by exiting early and checking for error conditions, you avoid a whole lot of nesting in your code. Which will make it easier to read, and thus a whole lot easier to maintain. Not to mention finding out what error message goes to what check, as having 40 error messages in a row after ~500 lines (or more) of code is downright confusing even with proper indenting (without it's next to impossible).

 

In closing I'd just like to mention that there's a lot of login forms posted in this forum, and I've cleaned up and restructured quite a few of them the last few weeks. So a search of the forum will provide you with lots of examples, both on how to do it, how to not do it, and the differences between the two. ;)

Link to comment
Share on other sites

This is the rest of my assignment lol fun fun. Maybe some of you can see why I'm doing things oddly. Directions seem strange even to a 2 month old to php. 7 and part of 8 are done and due tomorrow. grrr. He still hasnt answered me

 

 

7. For now, create a 'registered_users.txt' file in your CISS225 directory. Add a few lines manually for login credentials that are delimited like so:

FIRST|LAST|EMAIL|PASSWORD

Mat|Caitore|m.caitore@xxxx.edu|myPassword

Derek|Jeter|jeter@yankees.com|yanksRule

 

8. In the library.php file, write a function called checkLogin. It will take two arguments (email, password). It will read in the registered_users.txt file, and check for a match. If a match on BOTH email AND password is found in the same line, it will return the value 0. If the entire file is scanned and no match is found, it will return the value 1.

 

9. In assignment3_process.php, call the checkLogin function after validating the fields as above. If the function returns a 0, generate a random session ID (at least 5 digits) and set it is a session variable. Set a SESSION variable for the email address used to log in. Also, set a session variable called LOGGED_IN (this can be set to 1 or 'Y'). Upon successful login, redirect the user to welcome.php. Upon failed login, set a COOKIE message like above and direct them back to the login page (assignment3.php) where the message will be displayed.

 

10. Add code to assignment3.php to check for an existing sessionID and LOGGED_IN. If they are both present, direct the user to welcome.php.

 

11. In library.php, write a function called getUserName that takes one argument (an e-mail address), scans the registered_users.txt file for the e-mail, and returns the full name as a single string (I.E. 'Mat Cantore') if it finds a match, or 0 if it finds no match.

 

12. At the top of welcome.php, call the getUserName function. Supply the e-mail from the SESSION variable set above. Parse the response by splitting it into an array for every instance of a whitespace character. Display the first element of the array with a welcome message, like so:

"Welcome, Mat!"

Edited by Jptalon
Link to comment
Share on other sites

*Sighs* Old C-programmer I see, your professor. Even so, he has a lot of strange ideas on what constitutes good programming practices.

 

If we skip the whole clear-text password storage, I'd write the application quite a bit differently. Even if I were to use flat-files for storage.

First of all I'd store the username in the session array, or user ID if we had it available, and then skip the entire getUserName () function: It's not necessary, as you're fetching the username (and everything else) from the users file when logging in. Checking the session array for a set username provides the same function as the arbitrary "logged_in" index.

I would also never set a cookie with a message for the user, or redirect him upon a failed form submission. I'd show the the form anew, with the error message and the (properly escaped) submitted data. This will make things a lot quicker for the user, as he doesn't have to wait for another page load nor input all of the data again.

As for the splitting of the name to get just the first one, splitting it into an array is a bit unnecessary. I'd simply find the first space character, and use substr () to split the first name into a new variable.

 

Lastly with PHP the convention is to return true on success, and on errors false (-1, or something that evaluates to false) is usually returned. Your professor is using the old CLI "errorlevel" return values.

Link to comment
Share on other sites

I'd write the application quite a bit differently.

 

And you'd probably fail the course because of that. The instructions are very simple and clear: follow them.

 

-1, or something that evaluates to false

 

If you're going to give an example of something that evaluates to false, at least use something that evaluates to false!

Link to comment
Share on other sites

Salathe: I assumed he was capable of searching the PHP manual for himself, but if you insist:

http://php.net/manual/en/types.comparisons.php

 

Also, if I failed the course because of writing the application in a more secure and efficient manner, I'd lodge a complaint and explain my reasons. Referencing third parties, for extra validity. If the professor still doesn't agree, then it's his job to explain why his methods is better. Should he fail to do so, or reconsider the grading, I'd go to the administration.

 

Yes, I've done this previously. I've even taken over the class, when it was apparent that I knew more than the teacher. Which is how I got started with PHP in the first place, instead of writing an application in Access(!)

I attend school to learn stuff, not to blindly follow instructions.

Link to comment
Share on other sites

Salathe: I assumed he was capable of searching the PHP manual for himself, but if you insist:

http://php.net/manual/en/types.comparisons.php

 

I wasn't insisting anything, you gave an incorrect example and I called you on it.

 

Assuming anyone knows where to find the information available in the manual is a dangerous game to play, surely you have seen that by now.

 

Also, if I failed the course because of writing the application in a more secure and efficient manner, I'd lodge a complaint and explain my reasons.

 

Your employers and school will love you, I'm sure. Following simple instructions and raising potential issues with the course content are not mutually exclusive. It's not "my way or no way", as you continually keep preaching here on PHPFreaks.

Link to comment
Share on other sites

Ah, now I understand what you meant with the last quote. -1 wasn't used as an example as something that evaluates to false, which is why I used it and then wrote "or something that..." Had I meant to use "-1" as an example of something that evaluates to false, I would haven written "or something else that..."

 

As for your digression: I've yet to have any complaints, and the teachers I've had have been very supportive. I think you've misunderstood my intent a bit, but that's your prerogative to do.

Link to comment
Share on other sites

Lol you two are funny, but I am picking up a lot reading your posts and the web. So i have 2 sections here and wondering why its outputting as it does. The function checks and works as intended. But the IF statement that is calling kicks back the opposite of what i expect. I'm going to continue on regardless. Not much time left and had to get English done by noon.

if (checkLogin($email, $password)){
echo 'listed';
}else{
echo 'not listed';
}

No the echos are not staying. They were just for testing purposes.

function checkLogin ($email, $password){
$file = fopen('/homepage/registered_users.txt', 'r');
if (!$file){
echo 'Could not open file';
exit;
}
else {
while (!feof($file)) {
$line = fgets($file, 999);
 echo $line."<br />";
if ((strstr($line, $email)) && (strstr($line, $password)))
echo 'yes';

}
}
}

Link to comment
Share on other sites

You can separate the concerns of the checkLogin() function where:

 

1. checkLogin() verifies a email and password

2. readCsvLines() reads a csv file and returns an array

 

Disclaimer: not tested!

 

function checkLogin($email, $password) {
 $lines = readCsvLines('/homepage/registered_users.txt', '|', '', '');
 for ($found = false; !$found && current($lines); next($lines)) {
   $line = current($lines);
   if ($line['EMAIL'] === $email && $line['PASSWORD'] === $password)) {
     $found = true;
   }
 }
 return $found ? 1 : 0;
}

function readCsvLines($file, $dlm, $enc, $esc, $useFirstLineAsKeys = true) {
 $fh = fopen($file, 'r');
 $keys = array();
 $keysCount = 0;
 $lines = array();
 while (($data = fgetcsv($fh, 0, $dlm, $enc, $esc)) !== false) {
   if ($useFirstLineAsKeys) {
     $keys = $data;
     $keysCount = count($data);
     $useFirstLineAsKeys = false; // use this var as a one-off
     continue; // go to next line
   }
   if ($keys) {
     if ($keysCount !== count($data)) {
       // probs!
     } else {
       $lines[] = array_combine($keys, $data);
     }
   } else {
     $lines[] = $data;
   }
 }
 return $lines;
}

Edited by ignace
Link to comment
Share on other sites

You can separate the concerns of the checkLogin() function where:

 

1. checkLogin() verifies a email and password

2. readCsvLines() reads a csv file and returns an array

 

Disclaimer: not tested!

 

function checkLogin($email, $password) {
$lines = readCsvLines('/homepage/registered_users.txt', '|', '', '');
for ($found = false; !$found && current($lines); next($lines)) {
$line = current($lines);
if ($line['EMAIL'] === $email && $line['PASSWORD'] === $password)) {
$found = true;
}
}
return $found ? 1 : 0;
}

function readCsvLines($file, $dlm, $enc, $esc, $useFirstLineAsKeys = true) {
$fh = fopen($file, 'r');
$keys = array();
$keysCount = 0;
$lines = array();
while (($data = fgetcsv($fh, 0, $dlm, $enc, $esc)) !== false) {
if ($useFirstLineAsKeys) {
$keys = $data;
$keysCount = count($data);
$useFirstLineAsKeys = false; // use this var as a one-off
continue; // go to next line
}
if ($keys) {
if ($keysCount !== count($data)) {
// probs!
} else {
$lines[] = array_combine($keys, $data);
}
} else {
$lines[] = $data;
}
}
return $lines;
}

I like that even though its well beyond my 8 week php noobness lol. But unfortunately I have to follow the directions I posted earlier. I was just curious as to why i was getting contradicting outputs.

 

Side note, he graded my second assignment from a month ago. I had asked him for help 4x and got none, so I turned it in at about 60% complete. He did not correct it so I cant even see how it was finished. Would have been nice cause I could use some of it in this. He gave me a 100% and said Perfectly done. Sigh.....I need to learn this, not just pass the class

Link to comment
Share on other sites

On the last leg and fading fast, might turn it in incomplete. Number 11 is eluding me on which function will work.

 

11. In library.php, write a function called getUserName that takes one argument (an e-mail address), scans the registered_users.txt file for the e-mail, and returns the full name as a single string (I.E. 'Mat Caitore') if it finds a match, or 0 if it finds no match.

 

12. At the top of welcome.php, call the getUserName function. Supply the e-mail from the SESSION variable set above. Parse the response by splitting it into an array for every instance of a whitespace character. Display the first element of the array with a welcome message, like so:

"Welcome, Mat!"

 

Here is my 3 pages so far in working form.

 

Form page:

<html>
<body>
<?php
session_start();
require('/homepage/library.php');
//if (isset($_POST['email']) && isset($_POST['password'])) {
if (isset($_COOKIE['error'])){
echo $_COOKIE['error'];
}
if (isset($sessionID, $LOGGED_IN)) {
Header ('Location: http:///Welcome.php');
}
?>
<form method="post" action="assignment3_process.php">
Email:<br />
<input type="text" name="email" size="35" />
<br />
Password:<br />
<input type="password" name ="password" size="35" />
<br />
<input type="submit" />
</form>
</body>
</html>

Form_processing page:

<?php
include ('/homepage/library.php');
$email = $_POST['email'];
$password = $_POST['password'];
if (validate($email, 1)) {
}
if (validate($password, 2)) {
}else{
setcookie('error', 'Invalid email or password', 0);
Header ('Location: http:///assignment3/assignment3.php');
echo $_COOKIE['error'];
}
if (!checkLogin($email, $password)){
$sessionID = rand(1,99999);
$SESSION = $_POST['email'];
$LOGGED_IN = 1;
Header ('Location: http:///Welcome.php');
}else{
setcookie('error', 'Invalid email or password', 0);
Header ('Location: http:///assignment3/assignment3.php');
}
?>

Library page:

<?php
//$email = $_POST['email'];
//$password = $_POST['password'];
//echo $email;
//echo $password;
function validate($string_to_validate, $type_of_validation){
switch($type_of_validation){
 case '1':
 $email = $_POST['email'];
 if (!preg_match('^[a-zA-Z0-9_\-\.]+@[a-zA-z0-9\-]+\.[a-zA-Z0-9\-\.]+$^', $email)){
  return false;
  }else{
   return true;
   }
 case '2':
   $password = $_POST['password'];
   if (!preg_match("/^.*(?=.{8})(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).*$/", $password)){
  return false;
  }else{	 
  return true;
   }
}
}
function checkLogin ($email, $password){
$file = fopen('/homepage/registered_users.txt', 'r');
if (!$file){
 echo 'Could not open file';
exit;
}
else {
while (!feof($file)) {
$line = fgets($file, 999);
if ((strstr($line, $email)) && (strstr($line, $password)))
echo ''; //yes i know
}
}
}
?>

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.