Here, i build one form validation script in php using understanding SOLID
concept.
My question is the way i coded my code is true way for OO
concept ?
Use of abstract class and the extend it, is that true way ?
can i strongly use interface for this functionality ?
i use namespace
but i can't include using use
keyword and the filenamespace\classname
. can i have must be include
or require
function call with relative filename of class and then call use
keyword.
form.php
<!DOCTYPE html>
<html>
<head>
<title>PHP VALIDATION</title>
<?php
$txt_name = '';
$txt_email = '';
$txt_number = '';
$txt_password = '';
$txt_password2 = '';
// require validation class
require_once 'validate/validationClass.php';
$validae = new Validation();
$submit = filter_input(INPUT_POST, 'submit');
$server_request = filter_input(INPUT_SERVER, 'REQUEST_METHOD');
if (NULL !== $submit && $submit == "SUBMIT"):
$validae->validate();
$txt_name = $validae->valid('txt_name','Username','trim|required');
$txt_email = $validae->valid('txt_email','Email','trim|required|email');
$txt_number = $validae->valid('txt_number','Number','trim|required|numeric|min_length[9]');
$txt_password = $validae->valid('txt_password','Password','trim|required');
$txt_password2 = $validae->valid('txt_password2','Re Enter Password','trim|required|equalTo[txt_password]','','Password');
// form is valid
if($validae->is_valid()===1):
echo "form submitted";
endif;
endif;
?>
<style>
#form-add input, #form-add textarea, #form-add span{display:block;}
</style>
</head>
<body>
<form method="POST" id="form-add">
<label>Name:</label>
<input type="text" name="txt_name" value="<?php echo $txt_name?>"/>
<span><?php echo $validae->error('error_txt_name');?></span>
<label>Email:</label>
<input type="text" name="txt_email" value="<?php echo $txt_email?>"/>
<span><?php echo $validae->error('error_txt_email');?></span>
<label>Number:</label>
<input type="text" name="txt_number" value="<?php echo $txt_number?>"/>
<span><?php echo $validae->error('error_txt_number');?></span>
<label>Password:</label>
<input type="text" name="txt_password" value="<?php echo $txt_password?>"/>
<span><?php echo $validae->error('error_txt_password');?></span>
<label>Re Enter Password:</label>
<input type="text" name="txt_password2" value="<?php echo $txt_password2?>"/>
<span><?php echo $validae->error('error_txt_password2');?></span>
<input type="submit" name="submit" value="SUBMIT"/>
</form>
</body>
</html>
//validationAbstract.php
<?php
// namespace FormValid\Validate;
/**
* ValidateAbstract
*
* Validation Abstract Class
*
* @package formvalid
* @subpackage validate
* @category Validation
* @author Himanshu G Kubavat
* @link https://himanshukubavat.wordpress.com/
*
* @access inherited
*/
abstract class ValidateAbstract {
/**
* required
*
* @param mixed $value
* @return boolean
*/
protected function required($value) {
$val = trim($value);
return (empty($val)) ? 0 : 1;
}
/**
* numeric
*
* @param int $value
* @return boolean
*/
protected function numeric($value) {
return !(empty($value)) ? (preg_match("/^([0-9]*)$/", $value)) ? 1 : 0 : 0;
}
/**
* email
*
* @param mixed $value
* @return boolean
*/
protected function email($value) {
return !(empty($value)) ? (filter_var($value, FILTER_VALIDATE_EMAIL)) ? 1 : 0 : 0;
}
/**
* alphabetic
*
* @param mixed $value
* @return boolean
*/
protected function alphabetic($value) {
return !(empty($value)) ? (preg_match("/^[a-zA-Z ]*$/", $value)) ? 1 : 0 : 0;
}
/**
* alphanumeric
*
* @param mixed $value
* @return boolean
*/
protected function alphanumeric($value) {
return !(empty($value)) ? (preg_match("/^[-_a-zA-Z0-9. ]*$/", $value)) ? 1 : 0 : 0;
}
/**
* url
*
* @param mixed $value
* @return boolean
*/
protected function url($value) {
return !(empty($value)) ? (filter_var($value, FILTER_VALIDATE_URL)) ? 1 : 0 : 0;
}
/**
* phone
*
* @param int $value
* @return boolean
*/
protected function phone($value) {
return !(empty($value)) ? (preg_match("/^\+?[0-9\-]+\*?$/", $value)) ? 1 : 0 : 0;
}
/**
* date
*
* @param date $value
* @return boolean
*/
protected function date($value) {
$val = date("Y-m-d", strtotime($value));
return ($val == "1970-01-01" || $val == "0000-00-00") ? 0 : 1;
}
/**
* equalTo
*
* @param mixed $value1
* @param mixed $value2
* @return boolean
*/
protected function equalTo($value1, $value2) {
return !(empty($value1)) ? ($value1 == $value2) ? 1 : 0 : 0;
}
/**
* min_length
*
* @param int $value1
* @param int $value2
* @return boolean
*/
protected function min_length($value1, $value2) {
return !(empty($value1)) ? (strlen($value1) <= $value2) ? 1 : 0 : 0;
}
/**
* max_length
*
* @param int $value1
* @param int $value2
* @return boolean
*/
protected function max_length($value1, $value2) {
return !(empty($value1)) ? (strlen($value1) >= $value2) ? 1 : 0 : 0;
}
}
?>
//validationClass.php
<?php
// namespace FormValid\Validate;
/**
* Validation Class
*
* @package formvalid
* @subpackage validate
* @category Validation
* @author Himanshu G Kubavat
* @link https://himanshukubavat.wordpress.com/
*/
// use FormValid\Validate\ValidateAbstract as ValidateAbstract;
require_once __DIR__.'/validationAbstract.php';
class Validation extends ValidateAbstract {
private $error = array();
private $formdata = array();
private $form_is_valid = 1;
public function _construct() {
}
public function validate() {
$this->formdata = filter_input_array(INPUT_POST);
}
public function valid($name, $label, $valid_type, $custom_msg = NULL, $same_as_control_name=NULL) {
$validation_type = explode('|', rtrim($valid_type, '|'));
foreach ($validation_type as $validate):
if ($validate == "trim"):
$val = trim($this->formdata[$name]);
else:
$is_true = $this->call_validation($validate, $this->formdata[$name]);
if ($is_true === 1):
$val = $this->formdata[$name];
elseif ($is_true === 2):
$this->set_error($name, "Validation Method Not Exists");
else:
if (strpos($validate, '[') !== false):
$expMethod = explode('[', $validate,2);
$validate = $expMethod[0];
$arg2 = str_replace(']', '', $expMethod[1]);
if (method_exists($this, $validate)):
if($validate=="equalTo"):
$msg = $this->set_message($validate, $name, $label, $same_as_control_name, $custom_msg);
$this->set_error($name, $msg);
else:
$msg = $this->set_message($validate, $name, $label, $arg2, $custom_msg);
$this->set_error($name, $msg);
endif;
endif;
else:
$msg = $this->set_message($validate, $name, $label, $this->formdata[$name], $custom_msg);
$this->set_error($name, $msg);
$val = $this->formdata[$name];
endif;
endif;
endif;
endforeach;
return $val;
}
private function call_validation($function_name, $value) {
$respone = 2;
if (method_exists($this, $function_name)):
$respone = $this->$function_name($value);
else:
if (strpos($function_name, '[') !== false):
$expMethod = explode('[', $function_name,2);
$function_name = $expMethod[0];
$arg2 = str_replace(']', '', $expMethod[1]);
if (method_exists($this, $function_name)):
if($function_name=="equalTo"):
$respone = $this->$function_name($value,$this->formdata[$arg2],$value);
else:
$respone = $this->$function_name($value,$arg2);
endif;
endif;
endif;
endif;
return $respone;
}
private function set_message($method_name, $name, $label, $val, $message = NULL) {
if (empty($message)):
if (empty($label)):
return "{$name} " . $this->method_msg($method_name, $val);
else:
return "{$label} " . $this->method_msg($method_name, $val);
endif;
else:
return $message;
endif;
}
private function method_msg($method_name, $val = NULL) {
switch ($method_name) :
case "numeric": $msg = "is must be in numeric";
break;
case "email": $msg = "not valid!";
break;
case "alphabetic": $msg = "only alphabets!";
break;
case "alphanumeric": $msg = "only alpha numeric!";
break;
case "url": $msg = "not valid url";
break;
case "phone": $msg = "not valid phone";
break;
case "date": $msg = "not valid date";
break;
case "equalTo": $msg = "same as $val!";
break;
case "min_length": $msg = "minimum characters $val";
break;
case "max_length": $msg = "maximum characters $val";
break;
default:
$msg = "is must be required!";
break;
endswitch;
return $msg;
}
private function set_error($name, $message) {
$this->form_is_valid = 0;
$this->error["error_" . $name] = $message;
}
public function is_valid() {
return $this->form_is_valid;
}
public function error($error_control) {
if (isset($this->error[$error_control]) && !empty($this->error[$error_control])):
return $this->error[$error_control];
else:
return '';
endif;
}
}
?>
1 Answer 1
Security: XSS
All your fields are vulnerable to XSS, eg via this payload:
" autofocus onfocus="alert(1)
Structure
Use of abstract class and the extend it, is that true way ?
Not really. When you extend a class, you generally want to express that it is a type of that class. For example, you may have an Animal
abstract class, and a Cat
class which extends it, because a Cat is-a
Animal.
You on the other hand have a Validation
class, which isn't a type of ValidateAbstract
. ValidateAbstract
contains basic validation functions, and Validation
applies these functions, and also parses your validation codes. It's not so bad, but it isn't how inheritance is generally used.
If you wanted to use OOP, you may have a Validator
interface, which is implemented by an EmailValidator
, a PhoneValidator
, etc. But that is probably going to be overkill (except if you have more complex validation to do).
Usage
Your validator shouldn't care where the stuff it validates comes from. But you hardcoded POST into it. Instead, pass the values that need validating on to it.
Comments
Proper documentation is great, but your comments look auto-generated. They do not add any actual value.
Instead, you could for example document what phone numbers may look like (it's not like there is a widely accepted standard), how email addresses are verified, how dates may look, and so on.
Misc
- Why are
-_.
alphanummeric? - you say that your functions return a boolean, but they actually don't. In PHP,
1
and0
are not equal totrue
andfalse
; for example,false == array()
but0 != array()
,0 == "string"
butfalse != "string"
, etc. - I don't like using the ternary operator like this in PHP, because it doesn't work like it does in any other language. It's just difficult to read.
-
\$\begingroup\$ Thank you for your answer I'll definitely take up your advice :) really appreciate it. but can you explain me on namespace. I think! so overall i don't do anything related to oo and validation!. ; (. can i do validation in core php any other way ? \$\endgroup\$Himanshu– Himanshu2016年05月11日 12:09:52 +00:00Commented May 11, 2016 at 12:09
Explore related questions
See similar questions with these tags.