I have a php Form class designed to validate form input. However, I've run into some unexpected behavior when implementing an isEmailEmpty()
function. Here is my code:
class Form {
var $userEmail;
var $userPassword;
var $hashedPassword;
var $requiredPassLength = 6;
public function __construct($userEmail, $userPassword) {
$this->userEmail = $this->cleanInput($userEmail);
$this->userPassword = $this->cleanInput($userPassword);
}
public function cleanInput($dataField) {
$dataField = trim($dataField);
$dataField = stripslashes($dataField);
$dataField = htmlspecialchars($dataField);
return $dataField;
}
public function isEmailEmpty() {
return ($this->userEmail == "" || $this->userEmail == null) ? true : false;
}
public function isPasswordEmpty() {
return ($this->userPassword == "" || $this->userPassword == null) ? true : false;
}
public function isEmailValid() {
return filter_var($this->userEmail, FILTER_VALIDATE_EMAIL);
}
public function isPasswordValid() {
return (strlen($this->userPassword) >= $this->requiredPassLength) ? true : false;
}
public function hashPassword() {
return $this->hashedPassword = password_hash($this->userPassword, PASSWORD_BCRYPT);
}
// More functions down here...
Now, lets say I've instantiated an object in the following way:
$userEmail = "example@example.com";
$userPassword = "rootatoot";
$form = new Form($userEmail, $userPassword);
Since my isEmailValid()
function returns a bool, I expect to receive a boolean return value, i.e, true/false or 1/0 upon excecution. However, that is not the case. Instead, when the expression evaluates to true, I get a string output of the email value tested. For instance, given the object instantiated above, the statement echo $form->isEmailValid()
outputs example@example.com
. Running gettype($form->isEmailValid)
returns string
, which also was not expected. What's even more curious: the isPasswordValid()
function does NOT behave this way. Running $form->isPasswordValid()
returns 1
if the password is in fact valid. Running gettype($form->isPasswordValid())
returns boolean
, as expected. It's also interesting that my code still works as expected. For instance, the block
if ($form->isEmailValid()) {
echo "Valid email";
} else {
echo "Invalid email";
}
always gives the correct output. Even though my code is running as expected, it's still important to understand what's happening behind the scenes and why. So, my questions regarding this behavior are:
I appreciate any information you can provide. Thanks!
Since my isEmailValid() function returns a bool
Well, no, it doesn't.
From the documentation of filter_var
:
Returns the filtered data, or
FALSE
if the filter fails.
Your if
logic still worked because a non-empty string is "truthy", meaning it will be treated the same as true
when used as a condition.
In order to have isEmailValid
actually return a boolean, you can change your code to this:
public function isEmailValid()
{
return filter_var($this->userEmail, FILTER_VALIDATE_EMAIL) !== FALSE;
}
filter_var
doesn't return a boolean, it returns the value if it's valid, otherwise it returns false
. So you can rewrite your function as:
public function isEmailValid() {
return !!filter_var($this->userEmail, FILTER_VALIDATE_EMAIL);
}
Using !
twice will convert the value into a boolean.
Or, like your other functions, you can write:
public function isEmailValid() {
return filter_var($this->userEmail, FILTER_VALIDATE_EMAIL) ? true : false;
}
You don't need the conditional operator in the other functions, because they use operators that do return booleans, e.g. you could write:
public function isEmailEmpty() {
return ($this->userEmail == "" || $this->userEmail == null);
}
To answer your second question, it shouldn't be a problem if you always use your function in boolean contexts, such as if()
. No valid email should ever be falsy.