I was looking to see what would be the best way to handle errors from functions. Is the "DIE" method appropriate?
ie. php function calls another, for example:
function login(){
$result = verifyDetails("bob", "password123");
if($result == "accepted"){
echo "Welcome bob";
}else{
echo "Error!! \n";
echo $result;
}
}
function verifyDetails($user, $pass){
if(empty($user) || empty($pass)){
die("cannot be empty");
}
if($user == "bob" && $pass == "password"){
return "accepted";
}else{
die("username or password incorrect");
}
}
does the "DIE" method return the message or does everything come to a standstill?
thanks in advance
UPDATE
what if the output is not known?
for example. in the above example I have placed "accepted" as the only correct answer.
What if the return is a name or id number.. then you cant really separate the error and correct returns.
thanks again.
UPDATE / Possible Solution
function login(){
$result = verifyDetails("bob", "password123");
if($result[0] == "SUCCESS"){
echo "Welcome bob";
}else if($result[0] == "ERROR"){
echo "Error!! \n";
echo $result;
}else{
echo "Unknown Error!!";
}
}
function verifyDetails($user, $pass){
$msg = array();
if(empty($user) || empty($pass)){
$msg[0] = "ERROR";
$msg[1] = "cannot be empty"
return $msg;
}
if($user == "bob" && $pass == "password"){
//say $customerID is extracted from a db
$msg[0] = "SUCCESS";
$msg[1] = $customerID
return $msg;
}else{
$msg[0] = "ERROR";
$msg[1] = "username or password incorrect"
return $msg;
}
}
ideas & suggestions on the above "possible" solution are welcome
UPDATE
Check Shikiryu update 2 answer below for a cleaner version using arrays
die() just echo your message and stop the script because die() is an alias of exit().
In your case, since the password isn't password but password123, the script will stop just displaying "username or password incorrect".
But as I can see here, you want a return "cannot be empty";, so that it'll display :
Error!!
username or password incorrect
(and optionally the rest of the html which die() won't)
Update 2 (ugly way) :
function login(){
$result = verifyDetails("bob", "password123");
if(isset($result['success']){ // verifyDetails return true?
echo $result['success'];
}else{
echo "Error!! \n";
echo $result['error']; // Display the error verifyDetails throws
// You may want to check if $result['error'] exists.
}
}
function verifyDetails($user, $pass){
if(empty($user) || empty($pass)){
return array('error'=>"cannot be empty");
}
if($user == "bob" && $pass == "password"){
return array('success'=>"Welcome bob");
}else{
return array('error'=>"username or password incorrect");
}
}
die terminates the execution of the PHP script at the line it is called. Therefore, your message would no be returned.
You might want to simply use return instead of die;
Yes, you could use die() to debug.
does the "DIE" method return the message or does everything come to a standstill?
Yes, it returns the error message and yes, the script will stop continuing.
Well the only acceptable way in your case is return FALSE
if these functions are really methods of some class, use class variable to store actual errors.
if these functions belongs to no class, I wouldn't use them at all, but write it in plain code
if($user == "bob" && $pass = "password"){
echo "Welcome bob";
}else{
echo "incorrect username or password");
}
updated answer
Well there is nothing to invent. Just follow the way PHP goes:
Make your function return either value or FALSE
however, for the validation purpose you have to make it this way:
function validSomething($val){
return (bool)rand(0,1);
}
$err = array();
if (!validSomething($var)) {
$err[] = "Whatever error";
}
i.e. function returns only boolean values and actual error message being added by application logic.
However, in your example user-defined functions are totally misused.
Related
I am struggling to understand why my code is telling me that my username is undefined whenever I try to load up this page. the error is Notice: Undefined index: username in /home/jmask072/public_html/login.php on line 12. Any help is appreciated.
<?php
$users = array("user" => '$2y$10$yHL4GKr4pKxnBJ1L2xlqYuI/k0kviae2NbIQNJLFeXgVclT2hZeDi');
$isLoggedIn = false;
$errors = array();
$required = array("username", "pass");
foreach ($required as $key => $value) {
if (!isset($_POST[$value]) || empty($_POST[$value])) {
$errors[] = "please fill out the form";
}
}
if (array_key_exists($_POST['username'],$users)) {
$userPassword = $_POST['pass'];
$dbPass = $users[$_POST['username']];
if (password_verify($userPassword,$dbPass) === true) {
$isLoggedIn = true;
} else {
$isLoggedIn = false;
$errors[] = "Username not found or password incorrect";
}
} else {
$errors[] = "Username not found or password incorrect";
}
require_once("Template.php");
$page = new Template("My Login");
$page->addHeadElement("<link rel=\"stylesheet\" href=\"styles.css\">");
$page->addHeadElement("<script src='hello.js'></script>");
$page->finalizeTopSection();
$page->finalizeBottomSection();
print $page->getTopSection();
if (count($errors) > 0) {
foreach ($errors as $error) {
print "Error";
}
}
else if ($isLoggedIn === true) {
print "Hello, you are logged in";
}
print "<form action =\"login_action.php\" method =\"POST\" class=\"form-signin\">";
print "<h1>Please sign in</h1>\n";
print "<label for=\"inputUser\">Username</label>";
print "<input type=\"password\" name=\"pass\" id=\"inputPassword\" placeholder=\"password\">";
print "<button type=\"submit\"> Sign in</button>";
print $page->getBottomSection();
?>
first you should use a single quotes ' '
it is a very good alternative for backslash
and
print "<label for='inputUser'>Username</label>";
here you add label for inputUser but i dont see any input ??
You do need to make the script work even if the page is not requested correctly because you have no control on the requests it will get. Then you have to make sure that YOU call it correctly when you do it (right now this is not the case).
You are seeing the notice because, even if your code does check for the existence of the POST variables it needs (lines 6-10), even if the check fails it still attempts to read them at line 12.
The whole code block if...then...else starting at line 12 should only be executed if the checks went well (i.e. if(empty($errors)) {...). Now if the page is requested incorrectly at least you will get a useful error message that will help you understand where the problem is.
In this case the error message is "please fill out the form". In fact the code expects a form with two input fields but the one it displays only has the password field (which is unhelpfully labelled "Username") and has no username field. You need to provide both fields and make sure that the name attributes match the POST variables you want to get the data from (the for attribute in the label tags should also match the field name exactly).
I'm new here so I hope I do this right.
I am having some problems with sending the right message from my php to my
html.
Here you can see the php part that sould give a message back if the username isn't valid(if is uses #$%^& etc.)
$validUsername = $CurrentUser->ValidateUsername($username);
//if the input isn't filled send a message back
if(!$validUsername)
{
$messageError = "Please fill in a valid username";
header("location: ../public/index.php?messageError=$messageError");
}
and another one that should check if the username is unique
$uniqueUsername = $CurrentUser->CheckAvailableUsername($validUsername);
if (!$uniqueUsername)
{
$messageError = "Please fill in a unique username";
header("location: ../public/index.php?messageError=$messageError");
}
now the weird thing is if use #$%^&etc. as a username it will give me back a please fill in a unique username instead of please fill in a valid username and I can't find out why.
oh btw I made a class named User with these methods Ill show them below here.
public function ValidateUsername($username)
{
if (!empty($username))
{
if (isset($username))
{
if (!preg_match("/^[a-zA-Z ]*$/", $username))
{
return false;
}
return $this->username = $username;
}
return false;
}
return false;
}
And the other one.
public function CheckAvailableUsername($username)
{
$sql = "SELECT * FROM `tbl_todolist`
WHERE `username` = '$username';";
$result = $this->dataBase->query($sql)->rowCount();
if ($result == 1)
{
return false;
}
return $this->username = $username;
}
I really hope you guys can help me with this.
After header(...); you need to throw in a return; or exit; to exit right there, otherwise it continues beyond that header.
Additional Notes
You are open to SQL injection in CheckAvailableUsername, you need to sanitize the value before you get to that function and also escape/bind the value to your query instead. It looks like you are using PDO already.
I use CI 2.2 to build a simple login system. But I get problem when I try to generate session. Of course I have properly set up libraries (database, session) and User_M. When I retrieve data from database (without session), that's work fine. This is my Controller code:
public function verify()
{
// Define variable
$user = $this->input->post('username');
$pass = $this->input->post('password');
// Check input data
if (!empty($user) AND !empty($pass))
{
// Check match data from db
$checks = $this->User_M->check_user($user, $pass);
if($checks->num_rows() == 1)
{
foreach ($checks->result() as $check)
{
$sess = array (
'username' => $check->username,
'logged_in' => TRUE
);
$rest = $this->session->set_userdata($sess);
if ($rest)
{
echo "working";
} else {
echo "not working";
}
}
} else {
echo "Not found";
}
} else {
echo "You've empty field";
}
}
Additional explain, I check the result with if ($rest)...bla..bla..bla, that's echoing Not Working. Please let me know where's my mistakes?
Thank in advance
I think the problem is with this statement
$rest = $this->session->set_userdata($sess);
the set_userdata() does not return anything, so according to your condition it will always execute the else part.
Try to change your condition like this
if (!empty($this->session->userdata("username"))){
echo "Working";
}else{
echo "Not Working";
}
I need some help troubleshooting my code that's used for Log In validation. It's a combo of AJAX and PHP.
Here's the AJAX code that's directly in the login page.
<script language="javascript">
$(document).ready(function()
{
$("#login_form").submit(function()
{
$("#msgbox").removeClass().addClass('messagebox').text('Validating....').fadeIn(1000);
$.post("/ajax_login.php",{ user_name:$('#username').val(),password:$('#password').val()
,rand:Math.random() } ,function(data)
{
if (data=='no')
{
$("#msgbox").fadeTo
(200,0.1,function()
{
$(this).html('Incorrect Username or Password.')
.addClass('messageboxerror').fadeTo(900,1);
}
);
}
else if(data=='yes')
{
$("#msgbox").fadeTo
(200,0.1,function()
{
$(this).html('Logging in.....').addClass('messageboxok').fadeTo
(900,1, function()
{
document.location='/mainpage.php';
}
);
}
);
}
else
{
$("#msgbox").fadeTo
(200,0.1,function()
{
$(this).html('User is already logged in.').
addClass('messageboxerror').fadeTo(900,1);
}
);
}
});
return false;
});
$("#password").blur(function()
{
$("#login_form").trigger('submit');
});
});
</script>
PHP CODE:
<?
//Log In credentials
if ($rehash==$dboPW && $user_name == $dboUN && $logged=='Y'){echo "alreadyLogged"; exit;}
if ($rehash==$dboPW && $user_name == $dboUN && $logged=='N')
{
echo "yes";
$_SESSION['login'] = $username;
$_SESSION['password'] = $rehash;
$loggedUpdate=mysql_query("UPDATE Users SET LOGGED='Y' WHERE username='$user_name'");
exit;
}
else
{echo "no";}
?>
To summarize this process, someone logs in and the PHP script checks
if the username and password is valid AND that the person is NOT logged in already - returns value of 'yes'
if the username and password is valid AND that the person IS logged in already - returns value of 'alreadyLogged'
Invalid username or password - returns value of 'no'
This gets passed to AJAX, which SHOULD display the correct messages based on the return values from the php script. For reference (using the above summary):
AJAX should return: Logging in...
AJAX should return: User is already logged in.
AJAX should return: Invalid Username or Password.
The problem is this: If someone logs in correctly and IS NOT already logged in, message 2 appears instead of message 1. (I think that message 1 may appear but it disappears so fast).
I think the culprit is AJAX but unfortunately I'm not as familiar with it as I am with PHP.
I think the problem is with your php code.Your ajax code looks fine
try this
if ($rehash==$dboPW && $user_name == $dboUN && $logged=='Y')
{
echo "alreadyLogged"; exit;
}
elseif ($rehash==$dboPW && $user_name == $dboUN && $logged=='N')
{
}
I think it is the php problem,it occur an error and return the error message. if ajax_login.php does not return "yes" or "no" it will show the second message, whatever it returns.
Just need modify your PHP. try this :
//Log In credentials
// check if post if (isset($_POST)) {
// must initially to use check if on loggin
session_start();
// set variable post
$username = $_POST['user_name'];
$password = $_POST['password']; // change if use sha1 or md5
$rand = $_POST['rand'];
// check query database
$query = mysql_query("SELECT * FROM Users WHERE username='$username' AND password='$password'");
$user = mysql_fetch_array($query);
$row = mysql_num_rows($query);
if ($row > 0) {
if ($user['LOGGED'] == 'Y') {
echo "yes";
$_SESSION['login'] = $username;
$_SESSION['password'] = $rehash;
$loggedUpdate = mysql_query("UPDATE Users SET LOGGED='Y' WHERE username='$user_name'");
exit;
} elseif ($user['LOGGED'] == 'N') { // you can use 'else'
echo "alreadyLogged";
exit;
}
} else {
// invalid value password and username
echo "no";
exit;
} }
How do I get this to not display when you first go to the page???
if ($error) {
echo "Error: $error<br/>";
}
if ($keycode) {
echo "Keycode: $keycode<br/>";
}
<?php
session_start();
if ($_SESSION['been_here'] == true) {
// show what you need to show
}
else {
// don't show it
$_SESSION['been_here'] = true;
}
?>
The point here is that $_SESSION-variables "last" (as long as you session_start()).
Google "php sessions" for more information, and ask more questions on SO if necessary. :)
Use session_destroy(); to destroy the session.
<?php
if ($error){ echo "Error: $error
"; } if ($keycode) { echo "Keycode: $keycode
"; }
Based on the comments, it seems that your conditional is evaluating to true before you expect it to. Without seeing more of your code, this is only a guess, but I believe your problem is that you're giving the variable $error a default/temporary value when you create it that doesn't mean false. For example:
$error = "default error message, change me later";
// Later...
if ($error) { // This evaluates to true
echo "Error: $error<br/>";
}
If so, you'll want to check out PHP's documentation on casting to booleans, and maybe use something like this (with contribution from Christian's answer):
$error = "0"; // Default error message, change it later
// Later...
if($_SESSION['been_here'] == true)
$error = "This is the real error message.";
// Even later...
if ($error) {
echo "Error: $error<br/>";
}
This probably works for you:
if (isset($error) && !empty($error)) {
echo "Error: $error<br/>";
}
I cannot say more, because you have not specified what the value of $error might be.
Or you just have to introduce a flag that indicates that an error occurred:
$error = 'Error message.';
$has_error = false;
if(!empty($_POST) && some_condition) { // means it is a POST request
$has_error = true;
}
if($has_error) {
echo "Error: $error<br/>";
}