I make a form validation and I want to that function display errors below input. Now the function display errors in top site. I don't know where is problem. Errors should display after click submit button.
class UserValidation{
private $data;
private $errors = '';
public function __construct($data)
{
$this->data = $data;
}
public function validateName()
{
$val = trim($this->data['first_name']);
if(empty($val))
{
return $this->errors = "Empty field";
}
else if(!preg_match('/^[a-zA-Z-0-9]{3,12}$/', $val))
{
return $this->errors = "Wrong first name";
}
}
if(isset($_POST['submit'])){
$validation = new UserValidation($_POST);
$error = $validation->validate_First_Name();
}
">
<div class="row">
<div class="form-group col-xl-12 text-light">
<label>Login</label>
<input type="text" name="first_name" class="form-control">
<div class="error">
<?php echo $error ?? '' ?>
</div>
</div>
</div>
</form>
There are a ton of different ways to do form validation. What you're doing is overly complicated, and as #El_Vanja stated, you shouldn't be throwing exceptions unless something important happens, and incorrectly entering info into a form is extremely common and is to be expected. When validating a form, all you really need to return is the error message.
Edit: this is definitely not production ready as there are plenty of missing parts; this is just an example to give you some ideas regarding validation.
This also puts your error messages below the submit button; which I don't recommend doing as they could be missed if out of the viewport.
<?php
class UserValidation {
public function __construct()
{
# define our errors array
$this->errors = [];
}
# returns any error messages in the errors array
public function errors() {
return $this->errors;
}
public function validate($key, $value)
{
# 'clean' the input
$val = strip_tags(trim($value));
# only validate if it's not the submit button
if($key == 'submit')
{
if($val == '') {
$this->errors[$key] = $key . ' can not be empty';
}
# this is a bad idea as people have apostrophes, etc. in their names
if(!preg_match('/^[a-zA-Z-0-9]{3,12}$/', $val)) {
$this->errors[$key] = $key . ' can only contain letters and numbers';
}
# perform other validation rules here...
}
return $value;
}
}
$v = new UserValidation();
# check if the form was posted using $_SERVER['REQUEST_METHOD']
if($_SERVER['REQUEST_METHOD'] == 'POST') {
# loop through the $_POST array
foreach($_POST as $key => $value) {
# run each form field through the validate function
$v->validate($key, $value);
}
}
?>
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<form action="index.php" method="post">
<div class="row">
<div class="form-group">
<label>Login</label>
<input type="text" name="first_name" class="form-control">
</div>
</div>
<div class="row">
<button type="submit" name="submit">Submit</button>
</div>
<div class="row">
<?php
# loop through the errors array and print each error
foreach($v->errors() as $error) {
echo '<span class="text-danger">'.$error.'</span><br>';
}
?>
</div>
</form>
</div>
</body>
</html>
Related
I want to validate form register and I created class UserValidator and I try to check if the username field exists. In my opinion everything is correct, but show me 2 errors
Warning: array_key_exists() expects parameter 2 to be array, null given in C:\xampp\htdocs\class\index.php on line 22
Notice: username is not present in data in C:\xampp\htdocs\class\index.php on line 24.
<?php
if(isset($_POST['submit']))
{
$validation = new UserValidator($_POST);
$errors =$validation->validateForm();
}
<?php
class UserValidator
{
private $data;
private $errors =[];
private static $fields =['username', 'email'];
public function _construct($post_data)
{
$this->data = $post_data;
}
public function validateForm()
{
foreach(self::$fields as $field)
{
if(!array_key_exists($field, $this->data))
{
trigger_error("$field is not present in data");
return;
}
}
$this->validateUsername();
return $this->errors;
}
private function validateUsername()
{
$val = trim($this->data['username']);
if(empty($val))
$this->addError('username', 'username cannot be empty');
else
{
if(!preg_match('/^[a-zA-Z-0-9]{6,12}$/', $val))
{
$this->addError('username', 'username must me 6-12 characters');
}
}
}
private function addError($key, $val)
{
$this->errors[$key] = $val;
}
}
?>
<div id="register">
<h1>REJESTRACJA</h1>
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<div class="row">
<div class="col-25">
<label for="loginRe">Login</label>
</div>
<div class="col-75">
<input type="text" name="username" placeholder="Login...">
<div class="error">
<?php echo $errors['username'] ?? '' ?>
</div>
</div>
</div>
<div class="row">
<div class="col-25">
<label for="email">Email</label>
</div>
<div class="col-75">
<input type="text" name="email" placeholder="Email...">
</div>
</div>
<div class="button">
<input type="submit" name="submit" value="Utwórz konto">
</div>
<div class="displayCenter">
<div class="display">
</div>
</div>
</form>
</div>
$this->data is NULL, it is not filled by constructor, the constructor declaration has a typo, missing one _
public function __construct($post_data)
{
$this->data = $post_data;
}
Constructor declaration has a typo, please rectify
I want to validate my form post using function and then insert it into database.
I have been able to do that without putting it into function but when i put it into a function it inserts without validating the input fields.
Thanks ;)
Here is my code:
<?php
function validate_post(){
global $link;
if (isset($_POST['submit'])) {
$error = array();
if (!isset($_POST['cat_title']) || empty($_POST['cat_title'])) {
$error[] = "field cannot be empty";
} else {
//check if a name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z]*$/", $_POST['cat_title'])) {
$cat_err = "Only letters and whitespace allowed";
}
}
//if no errors found
if (empty($error) && empty($cat_err)) {
$cat_title = htmlentities($_POST['cat_title']);
$sql = "INSERT INTO categories(cat_title)VALUES('$cat_title')";
$insert = mysqli_query($link, $sql);
confirm_query($insert);
if (mysqli_affected_rows($link) == 1) {
$post_info = "Category has been added";
redirect("categories.php");
} else {
$post_info = "Adding category failed";
}
} else {
$post_info = "Field cannot be empty";
}
}
}
?>
<?php validate_post(); ?><!-- call validate_post function-->
<!-- ADD CATEGORY FORM -->
<form action="" method="post">
<?php
if(isset($post_info))echo $post_info."<br>";
if(isset($cat_err))echo $cat_err."\n" ?>
<div class="form-group">
<label for="cat_tile">Categories</label>
<input type="text" class="form-control" name="cat_title" id="cat_tile"/>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="+ Add Category" name="submit" >
</div>
</form>
You can pass your post data by reference to a function like this:
function checkFormValue(&$inputData) {
if (isset($inputData) && !empty($inputData)) {
return $inputData;
}
return "";
}
Call this function on $_POST data to validate it:
$catTitle = checkFormValue($_POST["cat_title"]);
var_dump($catTitle);
If it fails to validate than it will return empty string. Using this function you can check isset and for !empty many of your form fields.
below code will help you ..
<?php
function validate_post(){
global $link;
if (isset($_POST['submit'])) {
$cat_err = "";
if (!isset($_POST['cat_title']) || empty($_POST['cat_title']) || $_POST['cat_title']=="") {
$cat_err = "field cannot be empty";
} else {
//check if a name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z]*$/", $_POST['cat_title'])) {
$cat_err = "Only letters and whitespace allowed";
}
}
//if no errors found
if ($cat_err=="") {
$cat_title = htmlentities($_POST['cat_title']);
$sql = "INSERT INTO categories(cat_title)VALUES('$cat_title')";
$insert = mysqli_query($link, $sql);
confirm_query($insert);
if (mysqli_affected_rows($link) == 1) {
$cat_err = "Category has been added";
redirect("categories.php");
} else {
$cat_err = "Adding category failed";
}
} else {
$cat_err = "Field cannot be empty";
}
return $cat_err;
}
}
?>
<?php $data=validate_post();echo $data;?><!-- call validate_post function-->
<!-- ADD CATEGORY FORM -->
<form action="" method="post">
<div class="form-group">
<label for="cat_tile">Categories</label>
<input type="text" class="form-control" name="cat_title" id="cat_tile"/>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="+ Add Category" name="submit" >
</div>
</form>
Your function doesn't return any information. You need to tell it to return the errors, and then do something with them. You need to restructure the way messages are organized in your function, but the gist is this:
add return $error; to the end of your validate function.
Then in your page body:
<?php $errors = validate_post(); ?><!-- call validate_post function-->
<!-- ADD CATEGORY FORM -->
<form action="" method="post">
<?php
foreach($errors as $error)
{
echo $error;
}
?>
<div class="form-group">
So, change your validate function to save all messages into a single array, return the array, then process the items.
Variables declared inside a function only "exist" within the scope of that function. $post_info inside your function has no relationship to $post_info outside the function.
Try to pass in the $_POST array:
if (isset($_POST['submit'])){
validate_post($_POST)
}
function validate_post($post_array) {
// your code here
}
Matt first suggested this, but here is how you would do that.
Using your code this is the rundown to what you need to do for the function.
<?php
function validate_post($link, $data=[]) {
$error = array();
if (!isset($data['cat_title']) || empty($data['cat_title'])) {
$error[] = "field cannot be empty";
} else {
//check if a name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z]*$/", $data['cat_title'])) {
$cat_err = "Only letters and whitespace allowed";
}
}
//if no errors found
if (empty($error) && empty($cat_err)) {
$cat_title = htmlentities($data['cat_title']);
$sql = "INSERT INTO categories(cat_title)VALUES('$cat_title')";
$insert = mysqli_query($link, $sql);
confirm_query($insert); //This is another function you created???
if (mysqli_affected_rows($link) == 1) {
$post_info = "Category has been added";
redirect("categories.php");
} else {
$post_info = "Adding category failed";
}
} else {
$post_info = "Field cannot be empty";
}
}
if (isset($_POST['submit'])) {
include 'dbfile.php'; // Containing your db link variable if that is how you've done it
validate_post($link, $_POST); // Usually you need to pass your database link by reference also rather than by global.
}
?>
--html section--
I'm creating a function for PHP form validation. The idea is that if a user has not filled out a required field (for example, if a $_POST variable called "name" is empty), then the user will be warned.
This function doesn't seem to work, however:
function addError($x) {
if (!$_POST["$x"]) {
$error.="Please enter your $x";
}
}
echo $error;
I've isolated the problem down to the passing of the argument $x into $_POST, i.e. this line:
if (!$_POST["$x"]) {
Specifically, $_POST["$x"]. Is this the right way/syntax to pass an argument?
Thank you!
Your code should be like -
$error = '';
function addError($x, $error) {
if (!$x) { // Check for the data
$error.="Please enter your $x"; // Concatenate the errors
}
return $error; // return the error
}
echo addError($_POST[$x], $error); // Pass the data to check & the error variable
Try this.....
<form method="post">
<input type="text" name="name" />
<input type="submit" value="submit" />
</form>
<?php
$x=$_POST["name"];
function addError($x)
{
if ($x==null)
{
$error="Please enter your name";
}
else
{
$error='';
}
return $error;
}
echo addError($x);
?>
Try this :-
$error = "";
function addError($x)
{
global $error;
if ("" == $_POST['"'.$x.'"'])
{
$error.="Please enter your".$x;
}
}
addError("name");
echo $error;
I referenced above two answers and write some code for this question. It works when I tested. You might get some idea for your coding.
Here is my tested code.
PHP section
<?php
function check_error($x){
$error = "";
if(isset($_POST[$x]) && $_POST[$x] == ""){
$error = "Please Enter Data";
}
return $error;
}
echo check_error('txt_name');
?>
HTML section
<!DOCTYPE html>
<html>
<head>
<title> Testing </title>
</head>
<body>
<h1> Testing </h1>
<hr/>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<input type="text" name="txt_name" value="" placeholder="Your name" />
<input type="Submit" name="btn_submit" value="Submit" />
</form>
</body>
</html>
Make $error a global variable.
I'm trying to set up simple example for form validation, whether field is empty or not. If field is not empty action redirect me to page ok.php and if not back to formvalidation.php. and change css of the field. I have problem with returning error array back to formvalidation.php and testing it to change css for input field. What am I doing wrong?
formvalidation.php
<?php require("includes/functions.php"); ?>
<?php
global $errors;
?>
<form action="posting.php" method="p">
<ul>
<li id="field">
<label for="field">Contact person </label>
<input
<?php
if (empty($errors)) {
echo "style=\"background-color: #ECECEC;\"";
} else {
if (in_array("field", $errors)) {
echo "style=\"background-color: red;\"";}
} else {
echo "style=\"background-color: #ECECEC;\"";
}
}
?>
type="text" name="field"/>
</li>
<li>
<input id="saveForm" class="button_text" type="submit" name="submit" value="Submit" />
</li>
</ul>
</form>
action.php
<?php require("includes/functions.php"); ?>
<?php
$errors = form_validation ();
if (!empty($errors)) {
redirect_to("formvalidation.php");
} else {
redirect_to("ok.php");
}
?>
function
<?php
function form_validation () {
$errors = array ();
$required_fields = array('field');
foreach($required_fields as $fieldname) {
if (!isset($_POST[$fieldname]) || empty($_POST[$fieldname])) {
$errors[] = $fieldname;
}
}
return $errors;
}
After redirect $error variable is empty use $_SESSION
<?php
$_SESSION['error']=form_validation ();
if (!empty($_SESSION['error'])) {
redirect_to("formvalidation.php");
} else {redirect_to("ok.php");}
?>
And in formvalidation.php
$error=$_SESSION['error'];
unset($_SESSION['error']);
don't forget to ensure that session_start() is on the top of your code
Just take a look at this tutorial: http://www.html-form-guide.com/php-form/php-form-validation.html. It's implemented more object-oriented.
I have a page here: https://github.com/alexwaters/PWTKD-new-CMS/blob/master/taekwondo/schedule-dev.php that is not showing my session messages: <?php echo output_message($message); ?>
I have been trying to track down what the heck is wrong with them, but have no idea. They work on other pages but not this one.
Can someone please help me find the noobie mistakes I made?
Per request here is some of the code that may be relevant:
schedule-dev.php
<?php require_once("../includes/initialize.php"); ?>
<?php $schedules = Schedule::find_all();?>
<?php $messages = Messages::find_by_id(1);?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link href="css/style.css" rel="stylesheet" type="text/css" />
<script src="jquery-1.2.6.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#contactLink").click(function(){
if ($("#contactForm").is(":hidden")){
$("#contactForm").slideDown("slow");
}else{
$("#contactForm").slideUp("slow");
}
});
});
function closeForm(){
$("#messageSent").show("slow");
setTimeout('$("#messageSent").hide();$("#contactForm").slideUp("slow")', 2000);
}
</script>
...
<?php
if(isset($_POST['signupSubmit'])){
$signup = new Signup();
$signup->name = $_POST['name'];
$signup->age = $_POST['email'];
if($signup->save()) {
$session->message("We will contact you with details.");
redirect_to('schedule.php');
} else {
$message = join("test", $signup->errors);
}
}
?>
<?php echo output_message($message); ?>
<div id="contactFormContainer">
<div id="contactLink"></div>
<div id="contactForm">
<fieldset>
<label for="name">Name *</label>
<input id="name" type="text" />
<label for="email">Email address *</label>
<input id="email" type="text" />
<input id="sendMail" type="submit" name="signupSubmit" onclick="closeForm()" />
<span id="messageSent"></span>
</fieldset>
</div>
</div>
Signup.php
<?php
// If it's going to need the database, then it's
// probably smart to require it before we start.
require_once(LIB_PATH.DS.'database.php');
class Signup extends DatabaseObject {
protected static $table_name="signup";
protected static $db_fields=array('id', 'name','email');
public $id;
public $name;
public $email;
public $errors=array();
public function save() {
// A new record won't have an id yet.
if(isset($this->id)) {
// Really just to update the name
$this->update();
return true;
} else {
// Make sure there are no errors
// Can't save if there are pre-existing errors
if(!empty($this->errors)) { return false; }
// Make sure the name is not too long for the DB
if(strlen($this->name) >= 255) {
$this->errors[] = "Name must be <= 255 characters long.";
return false;
}
if(strlen($this->email) >= 255) {
$this->errors[] = "Email must be <= 255 characters long.";
return false;
}
if(empty($email)) {
$this->errors[] = "Please enter an email address";
return false;
}
//Finally add the item to the DB
if($this->create()) {
return true;
} else {
//
$this->errors[] = "Send failed, please contact us";
return false;
}
}
}
and some other generic class stuff
message method from session.php
public function message($msg="") {
if(!empty($msg)) {
// then this is "set message"
// make sure you understand why $this->message=$msg wouldn't work
$_SESSION['message'] = $msg;
} else {
// then this is "get message"
return $this->message;
}
}
Don't you need to add session_start() to you php file? Try doing that, let me know if that helps.
I had to use $this-email in the save method
I needed to make the form an actual post form
The session message wasn't being outputted(?) because it wasn't grabbing the post vars