Jump to content

Recommended Posts

Just changed my phone validation to this:

 

case "phone":
//strip out any characters which are not digits.
$value = preg_replace("/\D/","",$value);

//find length of the value which is left.
$len = strlen($value);

$phoneRegExp = '/^\\d{10,11}\\z/';

if($value==''){
$errors[] = "You did not enter a phone number.";
}
elseif(substr($value, 0, 1) != "0" || preg_match($phoneRegExp,$value) != 1){
$errors[] = "You did not enter a valid phone number.";
}
break;

 

Seems to work perfectly, thanks very much indeed for the regExp :)

 

Noticed another issue with auto-filling the form. When there are errors and I send them back to the form and fill in their data again into the fields, the fields which were not filled out before the initial submit display 'NULL' in the fields.

 

Any tips on how to deal with this? I use this code to re-display:

<?php if(isset($_POST['product_comments']) && !empty($errors)){print($_POST['product_comments']);} ?>

 

Edit: Just realized why it does that, because when I loop through the values, if some of the fields weren't filled out, I set the value to string NULL (this is for database insertion). When I set it to type NULL, I received errors from the insert.

 

I have set it to be equal to an empty string if any weren't filled out and it works ok now. Works with the insert too, although it's inserting nothing, got blank fields, but I can live with this.

 

Regards,

 

AoTB.

Edited by AoTBuNgLe
  • Replies 52
  • Created
  • Last Reply

Top Posters In This Topic

You only need this for the phone-validation:

case 'phone':
   if (!preg_match ($phoneRegExp, $value)) {
       $errors[] = "You did not enter a valid phone number.";
   }
   break;

 

You might also want to do something with the $value variable here, depending upon what you do with it later on.

I recommend defining the variables containing the RegExps before the loop; You only need to set them once, after all. ;)

Edited by Christian F.

If I post my code, it will help you understand a little more about my setup (you will probably be shocked when you see it and think 'what the hell is he doing here') but I'm very new. I've been a bit vague about my code also during this thread so i'll post it so you can see the logic. Here is the full action script:

 

 

<?php
include("core/init.inc.php");

//array containing the possible values of the form select lists, also used to select a specific product to display only information relating to
//that product (on the products page).
$get_values = array("benches","tables","bird_housing","planters","gates","bin_stores",
"sheds","pet_housing","default_product","default_service","decking",
"fencing","exterior_buildings","furniture_repairs","jet_washing");

if(isset($_POST['name'])){

//if script does not die, the user submitted the form. delete last element (submit button) as we do not need it.
(isset($_POST['submit'])) ? array_pop($_POST) : "";

//create array to hold any errors.
$errors = array();

//firstly, check to see if my required fields contain any data. if they dont we add errors to the error array.
if(empty($_POST['name']) || empty($_POST['phone'])){
$errors[] = "You must fill in the required fields marked with a RED asterix(*).";
}

//check to see if the errors array contains anything. if it does, we need to send the user back to the form and display the error.
//do not carry on if the if statement executes because we dont want to process any more as we know we are going to have to send them back anyway regardless.
if(!empty($errors)){
$output = $errors;
}
else{
//if the code reaches here, we have data inside the two required fields so carry on processing all of the data now.
//pass a reference of the value so that if any ARE set to string NULL, it also changes the original $_POST value which is what we insert.
foreach ($_POST as $post => &$value) {
if($value == ""){
$value = "";
}
else{
switch ($post) {

case "name":
//replace any characters which are not lower/upper case letters or a space character.
$value = preg_replace("/[^a-zA-Z ]/","",$value);
//trim the value to compensate for the possibility the user entered nothing but whitespace characters.
$value = trim($value);

if($value == "") {
$errors[] = "You must enter alphabetical characters for your name.";
}
break;

case "email":
if(!filter_var($value,FILTER_VALIDATE_EMAIL)){
$errors[] = "You did not enter a valid email address.";//give an example of an email someone@provider.com in form
}
break;

case "phone":
//strip out any characters which are not digits.
$value = preg_replace("/\D/","",$value);

//find length of the value which is left.
$len = strlen($value);

$phoneRegExp = '/^\\d{10,11}\\z/';

if($value==''){
$errors[] = "You did not enter a phone number.";
}
elseif(substr($value, 0, 1) != "0" || preg_match($phoneRegExp,$value) != 1){
$errors[] = "You did not enter a valid phone number.";
}
break;

case "user_comments":
$len = strlen($value);

if ($len > 400){
$less = ($len - 400);
$errors[] = "You must enter {$less} LESS characters in the 'Additional Comments' field.";
}
break;

case "product_options":
//if value is not found in the array, could be potential hack. Locate them straght away to the contact page again.
if(!in_array($value, $get_values)){
header("Location: index.php?page=contact");
}
break;

case "product_ref":

//checks to see if the length of the string is not equal to 7
if(strlen($value) != 7) {
$errors[] = "The product id you entered was not long enough, must be 7 numbers.";

}
//checks to see if any of the characters entered were not digits. if this executes, we know that the user entered something different
//than 7 digits so there is no need to carry on and check the ref no against the records so we break out of case prematurely.
if(!ctype_digit($value)){
$errors[] = "Product id's can only contain numbers.";
break;
}

//prepared statement which checks the product ref no submitted against a product ref in the database.
require("core/prepared_select_pref.php");

if($row != 1){
$errors[] = "Your Product ID did not match one of our products.";
}

break;

case "product_comments":
$len = strlen($value);

if($len > 400){
$less = ($len - 400);
$errors[] = "You must enter {$less} LESS characters in the 'Product Comments' field.";
}
break;

case "service_options":
//if value is not found in the array, could be potential hack. Locate them straght away to the contact page again.
if(!in_array($value, $get_values)){
header("Location: index.php?page=contact");
}
break;

case "service_comments":
$len = strlen($value);

if($len > 400){
$less = ($len - 400);
$errors[] = "You must enter {$less} LESS characters in the 'Service Comments' field.";
}
break;
}
}

}
}

//if the error array contains data, we had some errors during validation, so we display all of these error(s) to the user.
if (!empty($errors)){

$output = "<ul>";
foreach ($errors as $err => $error_value){
$output .= "<li>".$error_value."</li>";
$output .= "<hr>";
}
$output .= "</ul>";
}
else{//if there were no errors after all the validation, insert data to database.
require("core/prepared_insert.php");
if($row >= 1){
$output = "Your information has successfully sent!";
}
else{
//maybe send their information to my email instead if there is an issue with insert....probably the best idea rather than displaying an error.
$output = "There was an error receiving your information.";
}
}

}

if (isset($_GET['page']) && $_GET['page'] == "products") {



if (isset($_GET['order'])){

if(in_array($_GET['order'],$get_values)){
require("core/get_products.php");
}
else{
header("Location: index.php?page=products");
}
}
else{
require("core/get_products.php");
}
}


?>
<!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>
<title><?php echo "Gardenable - ".$title; ?></title>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<script type="text/javascript" src="js/clock.js"></script>
</head>

<body>
<div id="container">
<!--HEADER CONTENT-->
<div id="header">
<img src="images/gardenable1.fw.png" alt="Gardenable Logo" title="Gardenable" id="logo" border="0" />

<div id="navigation_div">
<img src="images/flowerbed.fw.png" alt="Navigation Image" id="flowerbed_img" border="0" />
<ul>
<li><a href="?page=home">Home</a></li>
<li><a href="?page=about">About</a></li>
<li><a href="?page=products">Products</a></li>
<li><a href="?page=services">Services</a></li>
<li><a href="?page=contact">Contact Us</a></li>
</ul>
</div>
</div>
<!--END HEADER CONTENT-->

<div id="content">

<?php include($include_page); ?>

</div>

<!--FOOTER CONTENT-->
<div id="footer">
<p id="copyright"><span class="yellow">Gardenable.com</span> <span style="font-size: 18px;">©</span> Copyright 2012</p>

</div>
<!--END FOOTER CONTENT-->

</div>
<p id="pageviews"><?php echo "Page Hits: ".$page_views; ?></p>
</body>
</html>

 

As you can see, the functions which are defined within the cases will only ever be set/used once in any looping of the code.

 

Kind regards,

 

AoTB.

Edited by AoTBuNgLe

Nothing shocking there, nor anything blatantly wrong, so don't worry too much. :)

That said, you have done things a bit overly complicated at times, and you really should look into user-defined functions. Not only will they help you keep your code organized, but you can also utilize the "exit early design pattern. That means checking for error conditions, and returning from the function as soon as possible. Something which will help limit the amount of nesting (blocks within blocks), and make it even easier to maintain your code.

 

I've gone through your code, reformatted it to be easier to read, and added some comments. You can find it on pastebin.com. All of my comments are prefixed with "FIXME:"

 

All in all, the code is pretty good for a beginner. Just need to plan things a bit more out before starting, I think, and look for ways in which you can reduce the amount of code needed. "Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away," after all. ;)

 

To get a little showcase of what I mean, you can take a look at a previous post I made. Where I've posted the PHP-code I use for the contact forms in my framework, and explained a bit on how it works.

Hopefully it'll help to give you some ideas on how to structure your code a bit better, and if you have any questions about mine feel free to ask. :)

Edited by Christian F.

Just looked at your review of the code. Thank you very much indeed for taking the time to do this, I am more than grateful. Even the small things like using die() after a header re-direct which I had no idea about and no one else has ever mentioned it anywhere else.

 

I'll do what you've said in the comments and re-post it just to make sure it is 100%.

 

I will now take a look at the second link.

 

Kind regards,

 

AoTB. :)

Edited by AoTBuNgLe

I am very eager to learn. I hope one day I can do this professionally. It wouldn't even be work to me, This is my passion.

 

Getting a syntax error with using unset() instead of array_pop():

 

​(isset($_POST['submit'])) ? unset($_POST['submit']) : "";

 

Unexpected T_UNSET....

 

Can't seem to find any information on unsetting superglobals. I've used unset() before on normal variables and it works fine. php.net doesn't seem to give much information on this. I thought it could have been because of a return value but unset doesn't return one.

 

Any thoughts? Have you ever had this problem before?

 

Regards,

 

AoTB.

The ternary operator isn't the best choice for checking stuff like that, as it is a statement instead of a construct. In short, it expects a returnable value in the true/false sections, which unset () isn't.

Change it to a proper IF-test, and it'll work.

 

So the problem isn't unsetting the global variable, or its index, but the placement of it inside the ternary statement.

Just on a slight tangent here :

Edit: Just realized why it does that, because when I loop through the values, if some of the fields weren't filled out, I set the value to string NULL (this is for database insertion). When I set it to type NULL, I received errors from the insert.
You shouldn't really insert NULL anywhere. It's somewhat couter intuative to tell the DB to "insert nothing", and if you do it wrong you end up inserting the string "NULL" rather than the statement. If there is nothing to insert, drop the field from the insert statement and set the fields default value to NULL in the table design.

It's funny you should say that because I was on a different forum not long ago and was told I shouldn't be inserting NULL I should only insert if there is a value. I know it's not right but I thought to myself because it's my own business site, I can live with the fact it inserts NULL.

 

Obviously I want to learn the correct way to insert information but I need to get my code working first. As soon as it's working I will take a look at the database and the insertion. I was given help with writing my query for the insert and it's a little complicated for me so I will leave it for now and come back to it later. Thanks for mentioning it though. (not overly complicated but I haven't had the time to actually site and study it, been trying to get the content finished on the site first).

 

@Christian F - Only just got on today, going to finish editing the code which I started last night, just trying to understand the logic, not sure what you were asking me to delete and what to leave but I will edit it and post the finished product.

 

Not sure if I need to delete the switch altogether because the whole reason I was using it was because I was looping through the array with a foreach(). Now that the foreach() is gone, i'm not sure a switch is necessary, maybe just separate if statements to check the values?

 

Anyway, I'll play about with it and see if I can get it working on my own first.

 

Cheers fellas.

 

Regards,

 

AoTB.

Edited by AoTBuNgLe

Ok here is my code:

 

 

<?php
include("core/init.inc.php");

//array containing the possible values of the form select lists, also used to select a specific product to display only information relating to
//that product (on the products page).
$get_values = array("benches","tables","bird_housing","planters","gates","bin_stores",
"sheds","pet_housing","default_product","default_service","decking",
"fencing","exterior_buildings","furniture_repairs","jet_washing");

if(isset($_POST['name'])){

//if script does not die, the user submitted the form. delete last element (submit button) as we do not need it.
if(isset($_POST['submit'])){
unset($_POST['submit']);
}
//create array to hold any errors.
$errors = array();

//firstly, check to see if my required fields contain any data. if they dont we add errors to the error array.
if(empty($_POST['name']) || empty($_POST['phone'])){
$errors[] = "You must fill in the required fields marked with a RED asterix(*).";
}

switch ($_POST) {

case "name":
//replace any characters which are not lower/upper case letters or a space character.
$_POST['name'] = preg_replace("/[^a-zA-Z ]/","",$_POST['name']);

//trim the value to compensate for the possibility the user entered nothing but whitespace characters.
$_POST['name'] = trim($_POST['name']);

if($_POST['name'] == "") {
$errors[] = "You must enter alphabetical characters for your name.";
}
continue;

case "email":
if(!filter_var($_POST['email'],FILTER_VALIDATE_EMAIL)){
$errors[] = "You did not enter a valid email address.";//give an example of an email someone@provider.com in form
}
continue;

case "phone":
//strip out any characters which are not digits.
$_POST['phone'] = preg_replace("/\D/","",$_POST['phone']);

//find length of the value which is left.
$len = strlen($_POST['phone']);

$phoneRegExp = '/^\\d{10,11}\\z/';

if($_POST['phone'] == ''){
$errors[] = "You did not enter a phone number.";
}
elseif(substr($_POST['phone'], 0, 1) != "0" || preg_match($phoneRegExp,$_POST['phone']) != 1){
$errors[] = "You did not enter a valid phone number.";
}
continue;

case "user_comments":
$len = strlen($_POST['user_comments']);

if ($len > 400){
$less = ($len - 400);
$errors[] = "You must enter {$less} LESS characters in the 'Additional Comments' field.";
}
continue;

case "product_options":
//if value is not found in the array, could be potential hack. Locate them straght away to the contact page again.
if(!in_array($_POST['product_options'], $get_values)){
header("Location: index.php?page=contact");
}
continue;

case "product_ref":

//checks to see if the length of the string is not equal to 7
if(strlen($_POST['product_ref']) != 7) {
$errors[] = "The product id you entered was not long enough, must be 7 numbers.";
}
//checks to see if any of the characters entered were not digits. if this executes, we know that the user entered something different
//than 7 digits so there is no need to carry on and check the ref no against the records so we break out of case prematurely.
if(!ctype_digit($_POST['product_ref'])){
$errors[] = "Product id's can only contain numbers."; break;
}

//prepared statement which checks the product ref no submitted against a product ref in the database.
require("core/prepared_select_pref.php");

if($row != 1){
$errors[] = "Your Product ID did not match one of our products.";
}

continue;

case "product_comments":

$len = strlen($_POST['product_comments']);

if($len > 400){
$less = ($len - 400);
$errors[] = "You must enter {$less} LESS characters in the 'Product Comments' field.";
}
continue;

case "service_options":
//if value is not found in the array, could be potential hack. Locate them straght away to the contact page again.
if(!in_array($_POST['service_options'], $get_values)){
header("Location: index.php?page=contact");
}
continue;

case "service_comments":

$len = strlen($_POST['service_comments']);

if($len > 400){
$less = ($len - 400);
$errors[] = "You must enter {$less} LESS characters in the 'Service Comments' field.";
}
break;
}

//if the error array contains data, we had some errors during validation, so we display all of these error(s) to the user.
if (!empty($errors)){

$output = "<ul>";

foreach ($errors as $err => $error_value){
$output .= "<li>".$error_value."</li>";
}

$output .= "</ul>";
}
else{//if there were no errors after all the validation, insert data to database.
require("core/prepared_insert.php");
if($row >= 1){

//redirect to a confirmation page - need to create first...use the same message as below on that page.
$output = "Your information has successfully sent!";
}
else{
//maybe send their information to my email instead if there is an issue with insert....probably the best idea rather than displaying an error.
$output = "There was an error receiving your information.";
}
}

}

if (isset($_GET['page']) && $_GET['page'] == "products") {



if (isset($_GET['order'])){

if(in_array($_GET['order'],$get_values)){
require("core/get_products.php");
}
else{
header("Location: index.php?page=products");
die();
}
}
else{
require("core/get_products.php");
}
}


?>
<!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>
<title><?php echo "Gardenable - ".$title; ?></title>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<script type="text/javascript" src="js/clock.js"></script>
</head>

<body>
<div id="container">
<!--HEADER CONTENT-->
<div id="header">
<img src="images/gardenable1.fw.png" alt="Gardenable Logo" title="Gardenable" id="logo" border="0" />

<div id="navigation_div">
<img src="images/flowerbed.fw.png" alt="Navigation Image" id="flowerbed_img" border="0" />
<ul>
<li><a href="?page=home">Home</a></li>
<li><a href="?page=about">About</a></li>
<li><a href="?page=products">Products</a></li>
<li><a href="?page=services">Services</a></li>
<li><a href="?page=contact">Contact Us</a></li>
</ul>
</div>
</div>
<!--END HEADER CONTENT-->

<div id="content">

<?php include($include_page); ?>

</div>

<!--FOOTER CONTENT-->
<div id="footer">
<p id="copyright"><span class="yellow">Gardenable.com</span> <span style="font-size: 18px;">©</span> Copyright 2012</p>

</div>
<!--END FOOTER CONTENT-->

</div>
<p id="pageviews"><?php echo "Page Hits: ".$page_views; ?></p>
</body>
</html>

 

Not sure why it isn't working? I presumed using a continue rather than a break statement in my switch would allow the cases to all be evaluated?

 

I'm kinda sure I need some kind of loop or separate if statements?

 

What are your thoughts? (I've clearly not followed what you said correctly but I was a little stuck last night on some parts so just did the ones I could do like adding the die() after the header().)

 

Didn't quite understand what you were asking in the comments regarding deleting the loop and using a continue statement in that if. Because it's not looping, that if statement will only be checked once so what is the point of continue?

 

Sorry

 

Edit: Just had a thought, should I be using array_keys() to return all the keys then use that value within the switch's condition?

 

 

Ok, no that didn't work.

 

What about putting the switch within a while loop and "while we get values out of $_POST, keep executing"??

AoTB.

Edited by AoTBuNgLe

You shouldn't be using a loop at all, as you have a finite and set number of fields that you're expecting. Just remove the switch (), case and break statements, and the code should work. (At least the validation bit. ;) )

Don't have time right now to look at the rest of the code in detail, but I'll have a look at it after the weekend.

Awesome, I ended up totally removing the switch and just validated everything separately. Updated some of the validation also.

 

Here is the new code:

 

if(isset($_POST['name'])){

    //unset $_POST['submit'], submit button.
    if(isset($_POST['submit'])){
  unset($_POST['submit']);
}

    //create array to hold any errors.
$errors = array();

//check required fields
if(empty($_POST['name']) || empty($_POST['phone'])){
   $errors[] = "You must fill in the required fields marked with a RED asterix(*).";
}

//VALIDATE NAME

//replace any characters which are not lower/upper case letters or a space character.
$_POST['name'] = preg_replace("/[^a-zA-Z ]/","",$_POST['name']);

//trim the value to compensate for the possibility the user entered nothing but whitespace characters.
$_POST['name'] = trim($_POST['name']);

if($_POST['name'] == "") {
$errors[] = "You must enter alphabetical characters for your name.";
}

   //VALIDATE EMAIL 

if(!filter_var($_POST['email'],FILTER_VALIDATE_EMAIL)){
$errors[] = "You did not enter a valid email address.";//give an example of an email someone@provider.com in form
}

//VALIDATE PHONE NUMBER

$phoneRegExp = '/^\\d{10,11}\\z/';

if($_POST['phone'] == ''){
$errors[] = "You did not enter a phone number.";
}
elseif(substr($_POST['phone'], 0, 1) != "0" || preg_match($phoneRegExp,$_POST['phone']) != 1){
$errors[] = "You did not enter a valid phone number.";
}

//VALIDATE USER COMMENTS 

//trim() the textarea value.
$_POST['user_comments'] = trim($_POST['user_comments']);

$len = strlen($_POST['user_comments']);

if ($len > 400){
$less = ($len - 400);
$errors[] = "You must enter {$less} LESS characters in the 'Additional Comments' field.";
}

//VALIDATE PRODUCT SELECT LIST

//if value is not found in the array, could be potential hack. Locate them straght away to the contact page again. 
if(!in_array($_POST['product_options'], $get_values)){
header("Location: index.php?page=contact");
die();
}

//VALIDATE PRODUCT REFERENCE NUMBER

//replace any characters which are not digits.
$_POST['product_ref'] = preg_replace("/\D/","",$_POST['product_ref']);

//checks to see if the length of the string is not equal to 7
if(strlen($_POST['product_ref']) != 7) {
$errors[] = "The product id you entered was not long enough, must be 7 numbers.";
}
else{
//prepared statement which checks the product ref no submitted against a product ref in the database. 
require("core/prepared_select_pref.php");
}

if(isset($row) && $row != 1){
$errors[] = "Your Product ID did not match one of our products.";
}

//VALIDATE PRODUCT COMMENTS

//trim() the textarea value.
$_POST['product_comments'] = trim($_POST['product_comments']);

$len = strlen($_POST['product_comments']);

if($len > 400){
$less = ($len - 400);
$errors[] = "You must enter {$less} LESS characters in the 'Product Comments' field.";
}

//VALIDATE SERVICE SELECT LIST

//if value is not found in the array, could be potential hack. Locate them straght away to the contact page again. 
if(!in_array($_POST['service_options'], $get_values)){
header("Location: index.php?page=contact");
die();
}

//VALIDATE SERVICE COMMENTS

//trim() textarea value.
$_POST['service_comments'] = trim($_POST['service_comments']);

$len = strlen($_POST['service_comments']);

if($len > 400){
$less = ($len - 400);
$errors[] = "You must enter {$less} LESS characters in the 'Service Comments' field.";
}


//++++++++++++++++++++++++++++++++++++++

//VALIDATION ENDED, CHECK FOR ERRORS


//if $errors is not empty, display errors.
if (!empty($errors)){

  $output = "<ul>";

foreach ($errors as $err => $error_value){
  $output .= "<li>".$error_value."</li>";
  }

$output .= "</ul>";
    }
else{
  require("core/prepared_insert.php");
if($row >= 1){
//redirect to a confirmation page - need to create first...use the same message as below on that page.
      $output = "Your information has successfully sent!";
}
else{
  //maybe send their information to my email instead if there is an issue with insert....probably the best idea rather than displaying an error.
  $output = "There was an error receiving your information.";
}
}

}

 

Still a bit more needs to be done but it's definitely getting there!

 

Regards,

 

AoTB.

The regular expression for the phone number doesn't seem to be working.

 

 

//VALIDATE PHONE NUMBER


$phoneRegExp = '/^\\d{10,11}\\z/';

if($_POST['phone'] == ''){
$errors[] = "You did not enter a phone number.";
}
elseif(substr($_POST['phone'], 0, 1) != "0" || preg_match($phoneRegExp,$_POST['phone']) != 1){
$errors[] = "You did not enter a valid phone number.";
}

 

If I enter 01255-711-789-, the OR part of the ifelse statement must execute as the first part is false, clearly..

 

When I enter 01255711789 it works. I think it worked before because I was using preg_replace('/\D/',"",$_POST['phone']) first, which strips out any NON digits, then I was using the other regExp.

 

I thought the preg_match() code was meant to still match the number even if the entered spaces or other characters?

 

I will use the preg_replace() code again before attempting to use the preg_match()..

 

Regards,

 

AoTB.

Edited by AoTBuNgLe

As you noticed the RegExp is indeed working, for the initial condition of 10-11 digits long. Since I'm not based in the UK, I didn't know that there were other alternatives you'd wanted to allow. That's one of the reasons one always should be as specific as possible when dealing with code, and RegExp in particular. ;)

 

The extended pattern would look something like this, depending upon where that 11th digit is (here I've assumed the first 0):

$phoneRegExp = '/\\d{10,11}|0?\\d{4}\\-\\d{3}\\-\\d{3}\\z/';

 

Also, matching input against empty and then matching it against a (more) specific rule is somewhat of a wasted effort. A missing phone number is an invalid phone number, after all, so just drop the first half of that test and show the invalid phone no message.

Better to be as specific with the validation messages as you can the first time around, so that people don't have to play hide and seek with the validation filter. It is really annoying to have to submit a form multiple times, just because you weren't told what was allowed (or everything that's not) the first time around. ;)

Thanks very much for your reply. I've gotta get ready for college (first day w00p w00p) so I don't really have time to play about with it but should be on after 9pm gmt+00 so i'll try to implement it then.

 

Regards,

 

AoTB>

It still didn't work bud. The last code I posted worked when I used the preg_replace() with the preg_match() so I will stick with that I think. Seems to work ok when I use the preg_replace().

 

I'm also having trouble with the name validation. Could you tell me exactly how that regExp works please?

 

 

//VALIDATE NAME

//trim the value to compensate for the possibility the user entered nothing but whitespace characters.
$_POST['name'] = trim($_POST['name']);

$length = strlen($_POST['name']);

$nameRegExp = '/^[a-zA-Z\\pL][\\w\\pL \\.\\-]'.$length.'\\z/u';

if(preg_match($nameRegExp,$_POST['name']) != 1){
$errors[] = "You did not enter a valid name.";
}

 

When I say it's not working, I mean it is allowing characters such as { and } into my DB. Should I just let them be entered or strip em out? I'm just cautious of people spoofing the form and entering '{}{}{}{}{}{}{}' for example.

 

Kind regards,

 

AoTB.

Edited by AoTBuNgLe

That code shouldn't validate anything, as the length variable doesn't contain a valid RegExp quantifier. I had intended for the Length parameter to contain either "+" or "{0,#}", where # is the maximum length accepted.

You might want to follow the link I posted above, and read up on RegExps. Should help you avoid these kind of problems later on. ;)

 

So why it's allowing anything in the database at all must mean that there's a logic problem somewhere in your code. I just did a test to prove the RegExp is indeed working as intended:

php > $length = '{0,20}';
php > $nameRegExp = '/^[a-zA-Z\\pL][\\w\\pL \\.\\-]'.$length.'\\z/u';
php > $name = array ("Christian", "Andre-3000", "Invalid{}");
php > foreach ($name as $test) {
   var_dump (preg_match ($nameRegExp, $test));
}
int(1)
int(1)
int(0)

 

When it comes to the code that does the testing, I recommend that you take a look at the phone validation example I posted on the previous page. Notice how I only use of line for the testing, only one test to determine whether or not the input is considered legit. You should do that for all validation in the same manner, without affecting the input at all.

 

As for those invalid characters: You shouldn't do any of those two choices. You should refuse to accept any input containing invalid data, and then show a message to the user explaining why the input was rejected. In fact, in my opinion you shouldn't even be trimming data before saving it, as it can significantly alter the user's experience.

So basically the point is, if the data is not what you are looking for, don't delete any characters from their input but still send them back to the form to correct it, auto filling with their exact value?

 

Also, when defining the length for myself, should I be using '{0, maxlength value defined in form?}'?

 

PS-Thanks for that site, it will prove very useful I'm sure.

 

Kind regards,

 

AoTB.

Edited by AoTBuNgLe
So basically the point is, if the data is not what you are looking for, don't delete any characters from their input but still send them back to the form to correct it, auto filling with their exact value?

Exactly!

Only don't send them back to the form, but just show the form again. Minor detail it might seem, but the difference is a header ("Location: ..") call, and a lot of code to handle said redirect. :P

 

Also, when defining the length for myself, should I be using '{0, maxlength value defined in form?}'?

Yes, this is to ensure that their input isn't cut off by the SQL storage engine (or have it return an error). In the former case it can create a lot of problems when trying to log in, effectively making their account inaccessible; And in the latter they wouldn't have the faintest idea why your site seems to be broken.

 

PS-Thanks for that site, it will prove very useful I'm sure.

You're very welcome, and it is immensely useful. That's what I used when properly learning RegExps. :)

 

Does the \\pL part of the reg exp have something to do with matching the different characters like the áéíóú ones?

Yes, as specified in the PHP manual. In the Unicode character properties, under PCRE.

Edited by Christian F.

Thanks very much for confirming that. I am not going mad.

 

I have been sitting here for about 2 hours reading up on regexp and the one I am dealing with, trying to work it out...I think i've figured out the first character set

 

Here is my attempt:

 

The caret used outside of an opening square bracket means we want to match characters specified in the character class. These are from a-z and A-Z. Using 2 backslashes means we want to escape its special use and use the literal? That literal backslash used with pL matches any of the unicode characters followed by any literal character?

 

Let me know!

 

Regards,

 

AoTB.

Edited by AoTBuNgLe

Let's do a quick run down of what the RegExp does:

/            # Opening delimiter, to mark the start of the RegExp.
^            # Binds the RegExp to the start of the string.
[a-zA-Z\\pL]        # First character must be one of the characters in this group (printable letter).
           # No quantifiers, so only 1 character is matched
[\\w\\pL \\.\\-]    # Second character group allows for any printable character, numbers, underscores,
           # periods and dashes.
{0,20}            # Repeated from 0 up to 20 times, inclusive.
\\z            # Ties the RegExp to the end of the string, disallowing any trailing newline characters.
/            # Closing delimiter, to mark the end of the RegExp.
u            # Unicode modifier, to enable the unicode (\p#) control sequences.

 

Also note that this allows the name to be up to 21 characters long, and since it allows for unicode letters the string can use up to 3 or 4 bytes per character. Not normally something you have to worry too much about, but nice to keep in mind still.

Edited by Christian F.

Thanks a lot for that explanation, I was way off! aha.

 

I was doing some tests with the 'test' code you gave me and changed the first array element to read "d'angelo" and it didn't return 1. What I did was added this - \' to the second character class like this: [\\w\\pL \'\\.\\-] and var_dump() then returned int(1)

 

 

So, searching {0,20} means search 21 times, {0,36} would mean search 37 times? 0 is also counted as being the first similar to array indexes?

 

Cheers again for explaining that.

 

Regards

 

AoTB.

Edited by AoTBuNgLe

Won't let me edit for some reason, I can get my head around everything pretty much except the \pL part.

 

Does the p hold a 'collection' of these special characters and the L means check for a match of one of those letters?

 

Regards,

 

AoTB.

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.