I have 2 problems here. First, I don't know how to use preg_match for filtering out digits and special characters, only letter and a & should be allowed to be contained.
Also, this script doesn't work how it should. I mean it works, but the switch statement only delivers the last string that contains an error, and if I put it inside the foreach, it gives out 1 time the first error and 3 times the second error.
What am I doing wrong? Please help me!
<?php
// test variables
$act1 = "SUBSCRIBEa";
$act2 = "SUBSCRIBEb";
$act3 = "SUBSCRIBE";
$act4 = "SUBSCRIBE";
// set error false as default
$error = "false";
// check if variables are ready for use
if(!empty($act1) && !empty($act2) && !empty($act3) && !empty($act4)) {
$acts = [$act1, $act2, $act3, $act4];
// check the acts for lenght, numbers and special characters
// add all of the acts to an array to loop over
foreach($acts as $key => $value) {
if($key < 9) {
$errorKey = "0{$key}";
} else {
$errorKey = $key;
}
// check the lenght
if(strlen($value) > 15) {
$error = "true";
$errorNumber = $errorKey;
}
/* check for numbers and special characters
if(!preg_match('/[^a-z&A-Z]/', $value)){
$error = "true";
$errorNumber = $error_{$errorKey};
}
*/
// declare a whitelist of things that should not produce an error
$whiteList = [
'SUBSCRIBE',
'SUB & LIKE',
'LIKE & COMMENT',
'DISLIKE',
'COMMENT',
'LIKE',
'FOLLOW',
];
// check if value from act is in the whitelist declared above, if its not, set `$error` to true and set `$error_*` (with key) to "true" as well.
if(!in_array($value, $whiteList)) {
$error = "true";
$errorNumber = $errorKey;
}
}
}
// deliver the error message
switch($errorNumber){
case 00:
echo "Something went wrong here 1 :o";
break;
case 01:
echo "Something went wrong here 2 :o";
break;
case 02:
echo "Something went wrong here 3 :o";
break;
case 03:
echo "Something went wrong here 4 :o";
break;
}
?>
Try the following code, I commented as much as I could to try to show you what I did to (possibly) fix your issue.
<?php
// test variables
$act1 = "SUBSCRIBEa";
$act2 = "SUBSCRIBEb";
$act3 = "SUBSCRIBE";
$act4 = "SUBSCRIBE";
// set error false as default
$error = false;
// check if variables are ready for use, if they are, add them to `$acts` array
// I do each check as a seperate line, as it looks cleaner than 1 long if statement.
$acts = [];
if(!empty($act1)) $acts[] = $act1;
if(!empty($act2)) $acts[] = $act2;
if(!empty($act3)) $acts[] = $act3;
if(!empty($act4)) $acts[] = $act4;
// declare a whitelist (outside of loop) of things that should not produce an error
$whiteList = [
'SUBSCRIBE',
'SUB & LIKE',
'LIKE & COMMENT',
'DISLIKE',
'COMMENT',
'LIKE',
'FOLLOW',
];
//create an empty array to hold errors
$errors = [];
// check the acts for lenght, numbers and special characters
// add all of the acts to an array to loop over
foreach($acts as $key => $value) {
//1 line ternary is cleaner than if/else statetmnt
$errorKey = $key < 9? "0{$key}" : $key;
//each row by default has no error
$hasError = 0;
// check the lenght
//use regex to check if a string only contains letters.
// check if value from act is in the whitelist declared above, if its not, set `$error` to true and set `$error_*` (with key) to "true" as well.
// make sure you use `||` (or) here, not `&&` (and), otherwise this statement will not work properly. If it's `||` only 1 thing has to be wrong, if it's `&&` then all of them have to be wrong.
if(strlen($value) > 15 || preg_match('/[^A-Za-z &]/', $value) || !in_array($value, $whiteList)) {
$error = true;
//if error occurs, set `$hasError` to 1, to later insert errorKey into array.
$hasError = 1;
}
//
if($hasError) {
//store error in array, to loop through later
$errors[] = $errorKey;
}
}
// deliver the error message
//Check if $error has been set to true at any point
if($error) {
//loop through error array, echo error message if $errorNumber matches.
//at this point we KNOW there was an error at some point, no need to use a switch really
foreach($errors as $errorNumber) {
echo "Something went wrong here $errorNumber :o";
}
}
?>
Related
Here I am having 5 fields:
clgID
empID
startDate
limit
papercode
Here all fields are mandatory, suppose any one of the field is empty means I have to return like clgID should not be empty OR empID should not be empty, as per my knowledge I written the code I had posted here, but I think my logic is not correct. I hope we have to do combination logic but I don't know how to write this logic in PHP. Please any one update my code
My code:
//Test Case : 1
$case1['testCase'] = 'Checking empty condition for all fields';
$case1['clgID'] = '';
$case1['empID'] = '';
$case1['startDate'] = '';
$case1['limit'] = '';
$case1['papercode'] = '';
foreach($mainArray as $key => $val){
$input['clgID'] = $val['clgID'];
$input['empID'] = $val['empID'];
$input['startDate'] = $val['startDate'];
$input['limit'] = $val['limit'];
$input['papercode'] = $val['papercode'];
// $response = GetResponse($API_URL.'resultTrail', $input);
if($val['clgID'] != '' && $val['empID'] != '' && $val['startDate'] != '' && $val['limit'] != '' && $val['papercode'] != '' )
{
$result[$key]['testCase'] = $val['testCase'];
$result[$key]['resultCode'] = 'c001';
$result[$key]['devTeamResult'] = 'success';
$result[$key]['testingTeamResult'] ='test case success';
}else
{
if($val['clgID'] == '' && $val['empID'] == '' && $val['startDate'] == '' && $val['limit'] == '' && $val['papercode'] == '' ){ // Checking empty condition for all fields
$result[$key]['testCase'] = $val['testCase'];
$result[$key]['resultCode'] ='458';
$result[$key]['devTeamResult'] = 'Parameter not matching min requirement';
$result[$key]['testingTeamResult'] ='test case failure';
$result[$key]['data'] = 'All fields mandatory';
}else{
if($val['clgID'] == '' ){ // Checking empty condition for clgID
$result[$key]['testCase'] = $val['testCase'];
$result[$key]['resultCode'] ='458';
$result[$key]['devTeamResult'] = 'Parameter not matching min requirement';
$result[$key]['testingTeamResult'] ='test case success';
$result[$key]['data'] ='clgID should not be empty';
}else{
if($val['empID'] == '' ){ // Checking empty condition for empID
$result[$key]['testCase'] = $val['testCase'];
$result[$key]['resultCode'] ='458';
$result[$key]['devTeamResult'] = 'Parameter not matching min requirement';
$result[$key]['testingTeamResult'] ='test case success';
$result[$key]['data'] = 'empID should not be empty';
}else{
if($val['startDate'] == '' ){ // Checking empty condition for startDate
$result[$key]['testCase'] = $val['testCase'];
$result[$key]['resultCode'] ='458';
$result[$key]['devTeamResult'] = 'Parameter not matching min requirement';
$result[$key]['testingTeamResult'] ='test case success';
$result[$key]['data'] = 'startDate should not be empty';
}
}
}
}
}
}
print_r($result);
Do you really want to be writing out that much code? What happens if you have to add another mandatory field?
Instead, be more generic.
$requiredFields = ["groupID", "studentID", "startFrom", "limit", "worksheetID"];
foreach($requiredFields as $key) {
if( empty($input[$key])) {
return $key." is required"; // or whatever error message
}
}
// if you get this far, ie. without hitting the "return", then all inputs are present.
// process the data now.
You can use this pattern for each input field:
$var = isset($_POST['field']) ? $_POST['field'] : '';
// Trim any trailing whitespaces
$conditionsOk = true;
if(trim($var) === '')
{
// Empty input
$conditionsOk = false;
}
if($conditionsOk) { // Perform action: db update, email... }
Let's take this opportunity to firstly, fix the issue to check if it's empty.
In php the isset() function checks if the index is in the array, and if it's empty.
Secondly, let's go over the code and clean it up a bit; please review the changes; clean code is the most important factor in being a successful developer.
else {
if (condition) {
}
}
Re-written to:
else if (condition) {
}
That's one of the issues with the code, the second issue is the cleanliness of the code; always try to keep the nested if statements to a minimum and move functionality to functions to keep the code readable and clean. - code that is not readable or maintainable doesn't carry any value.
I would go for a mapping and use a dynamic function.
Example mapping:
$fieldsMapping = [
"field" => exampleValidationFunction(),
"field2" => ["required" => True],
]
In return you can have flexibility and easily maintain the code albeit the learning curve.
The function to go over the mapping can be as follows:
function runTestCases() {
foreach ($fieldsMapping as $field => $validationRules) {
// your code here - check if its a function.. call function.. etc..
}
}
I am trying to validate an input using a form, through the use of an if statement.
if (isset($_POST['weekly-rate']))
{
$weekly_rate = $_POST['weekly-rate'];
if(!isset($_POST['weekly-rate']))
{
$error_messages[]= 'Weekly rate was not set';
}
else
{
$weekly_rateOK = true;
}
}
else
{
$error_messages[] = 'Weekly rate was not set...';
}
When I run this it gives doesn't give me the output I want, which is Weekly rent was not set. Am I incorrect in thinking that
if(!isset($_POST['weekly-rate']))
{
$error_messages[]= 'Weekly rate was not set';`
Means, if an input is not set, run the error message, weekly rate was not set.
However all I receive is nothing
Your understanding of isset() is correct. However, the form always posts the field back to your backend code which triggers isset() to be true all the time. You may look at using empty() instead.
A simplified version would look like this
$weekly_rateOK = !empty($_POST['weekly-rate']);
if (!$weekly_rateOK) {
$error_messages[] = 'Weekly rate was not set...';
}
You may need to add an integer check if needed.
If you are using a text input/select with a name, then the input/select is always posted and is set, but with an empty string. If it is a checkbox or radio buttons, then they will be set only if the checkbox is checked or a radio button is selected.
I have written a sample validation function, inspired by Laravel. You can check it here, and extend it by adding additional cases:
function validate ($rule_bag, $input) {
$flag = true;
$error_bag = [];
foreach ($rule_bag as $item => $rules){
$rules = is_array($rules) ? $rules : array_filter(explode(',', $rules));
foreach($rules as $rule){
$rule = trim($rule);
switch(mb_strtolower(trim($rule))){
case 'required': {
// checking isset then empty to be compatible with php <= 5.4
if (!isset($input[$item]) || empty($input[$item]))
{
$flag = false;
!isset($error_bag[$item])?$error_bag[$item]=[]:null;
$error_bag[$item][] = $rule;
}
break;
}
default: {
if (isset($input[$item])){
try {
if (!preg_match($rule, $input[$item])){
$flag = false;
!isset($error_bag[$item])?$error_bag[$item]=[]:null;
!isset($error_bag[$item]['regex'])?$error_bag[$item]['regex']=[]:null;
$error_bag[$item]['regex'][] = $rule;
}
}
catch(Exception $e){
echo $e->getMessage();
}
}
}
}
}
}
return $flag ? $flag : $error_bag;
}
So I am new to PHP, and am currently just doing a little project as practice, I've managed to get down a few lines of code without falling over... but am a bit stuck here.
Essentially, what my script currently does is check three different variables that I have set (each a true/false option) and distinguishes if there is only one true option selected (out of the 3 options, only one can be true, the other 2 must be false). If only 1 value is set to true, the rest of the code runs; if multiple values are set to true, or no values are set to true, it shows an error prompt for the user.
Once this check is done, I wanted to then set the value of $name for example, based on records linked to the relevant variable that is true... This is what I have come up with, but it doesn't seem to work...
if ($value1 == "true") {$name = $result1;}
else if ($value2 == "true") {$name = $result2;}
else if ($value3 == "true") {$name = $result3;}
else exit (0)
So i essentially want to set the $name variable by identifying which of the 3 value variables is true, and then setting $name with the relevant variable retrieved in the $result
Any help would be appreciated. And before anyone goes off on one... I know I may sound a bit mad... but we all have to start somewhere!!
Thanks
It would look much nicer with a switch:
switch(true){
case $value1:
$name = $result1;
break;
case $value2:
$name = $result2;
break;
case $value3:
$name = $result3;
break;
default:
exit();
}
In case you need to make sure only one of the statements is true, validate that prior using this:
//In case you need to make there is only a single true statement
$found = false;
for($i=1; $i<4; $i++) {
$value = "value".$i;
if($$value) {
if($found) {
exit("More than one 'true' statement");
}
$found = true;
}
}
Dracony's answer looks nice indeed, but will fail when multiple values are set to true. For more flexibility, you should consider mapping the values into arrays, and tracking the state (amount of values that are true) with a flag variable. Find a fully commented example that will satisfy all conditions below. Additionally, this code will work with arrays of any length (you can add conditions by simply putting more values in $values and $results).
// store the data in arrays for easier manipulation
$values = array($value1, $value2, $value3);
$results = array($result1, $result2, $result3);
// set a flag to check the state of the condition inside the loop
// it keeps track of the index for which the value is true
$flag = -1;
$name = NULL;
// use for and not foreach so we can easily track index
for ($i = 0; $i < count($values); $i++) {
// if no index has been found 'true' yet, assign the current result.
if ($values[$i] === true) {
if ($flag === -1) {
$flag = $i;
$name = $results[$i];
}
// if a 'true' value has been found for another index
// reset the name var & stop the loop
if ($flag > -1 && $flag !== $i) {
$name = NULL;
break;
}
}
}
if ($name) {
// run code when only 1 value is true
} else {
exit();
}
I'd like some help please, if its possible.
I have created two functions in order to display some messages when is set a $_GET after a redirect.Here's the code:
function display(){
if(isset($_GET['cnf_upd']) && $_GET['cnf_upd'] == '1'){
$value = "The update was successful!";
$type = "confirm";
construct_the_div($value, $type);
}
if(isset($_GET['err_upd']) && $_GET['err_upd'] == '1'){
$value = "The Update failed.";
$type = "error";
construct_the_div($value, $type);
}
if(isset($_GET['cnf_del']) && $_GET['cnf_del'] == '1'){
$value = "Deleted completely.";
$type = "confirm";
construct_the_div($value, $type);
}
if(isset($_GET['err_del']) && $_GET['err_del'] == '1'){
$value = "Unable to delete.";
$type = "error";
construct_the_div($value, $type);
}
}
function construct_the_div($value, $type){
// creating a div to display the message results
$div = "<div class=\"{$type}Msg\">\n";
$div .= "<p>{$value}</p>\n";
$div .= "</div><!-- end of {$type}Msg -->\n";
echo $div;
}
What I'd like to make is to try to improve the display function, as it gets longer and longer, so that there whould be only one (or two at most) if statement(s) if possible. So the value of the GET will be dynamicly inside the if condition and also if it has the preffix 'cnf_' it wil be a 'confirmMsg' and if it has the preffix 'err_' it wil be a 'errorMsg'.
Is it possible to make something like this???
function display() {
$messages = array(
'cnf_upd' => 'The update was successful!',
'cnf_err' => 'The Update failed.!',
// ...
// add all error and confirm there
// ...
);
foreach($_GET as $key => $value) {
if(strpos($key, 'cnf_')===0) {
$type = 'confirm';
$value = isset($messages[$key])
? $messages[$key]
: $key;
construct_the_div($value, $type);
}
if(strpos($key, 'err_')===0) {
$type = 'error';
$value = isset($messages[$key])
? $messages[$key]
: $key;
construct_the_div($value, $type);
}
}
}
The approach is not correct, it seems that only one message should occur at once (there cannot be "deleted completely" and "unable to delete" at once).
Try construct the parameters this way: ?msg=upd&msgType=cnf
function display(){
if (isset($_GET['msg']) && isset($_GET['msgType']))
{
$messages = array('cnf_upd'=>'The update was successful!',
'err_upd'=>'The update failed!',
'cnf_del'=>'The deletion was successful!',
'cnf_upd'=>'The deletion failed!',
);
if (isset($messages[$_GET['msgType'].'_'.$_GET['msg']))
construct_the_div($messages[$_GET['msgType'].'_'.$_GET['msg']], htmlspecialchars($_GET['msgType']));
}
there is still much to improve, but for start this is cleaner and safer.
I'm going to propose a different solution. Instead of setting different parameters in $_GET based on the message to be sent, set one parameter and parse its value.
// Start by setting integer constants:
define(CNF_UPD, 1);
define(ERR_UPD, 2);
define(CNF_DEL, 3);
define(ERR_DEL, 4);
Then when you set the value un $_GET, use the constant:
// Build the URL with a deletion error...
header("Location: http://example.com/script.php?msg=" . ERR_DEL);
Finally, use a switch to parse them
if (isset($_GET['msg'])) {
switch ($_GET['msg']) {
case CNF_UPD:
// Updated...
break;
case ERR_UPD:
// failed...
break;
// etc...
default:
// invalid code.
}
}
If you use a pattern of confirm/error/confirm/error for your integer constants, you can determine which it is by taking $_GET['msg'] % 2. Odd numbers are confirmations, evens are errors. There are of course many other ways you could lay this out, I just happen to have typed them in the alternating order you used. You could also do positive integers for confirmations and negatives for errors, for example.
$type = $_GET['msg'] % 2 == 1 ? $confirm : $error;
This is easily expanded to use multiple messages as well. Since they are integer values, you can safely construct a comma-separated list and explode() them when received.
$messages = implode(array(ERR_DEL,CNF_UPD));
header("Location: http://example.com/script.php?msg=$messages");
Unless you can somehow generate $value and $type based on the $_GET parameter (which I can't see how you would do), you could do something like:
$messages = array();
$messages[] = array('id' => 'cnf_upd', 'value' => 'The update was successful!', 'type' => 'Confirm');
$messages[] = array('id' => 'err_upd', 'value' => 'The Update failed.', 'type' => 'error');
...
foreach ($messages as $message) {
if(isset($_GET[$message['id']]) && $_GET[$message['id']] == '1'){
construct_the_div($message['value'], $message['type']);
}
}
I know this is embarrassing easy but I cannot get this to work right now, keep getting syntax errors, I just added in a jquery code that pre-fills in a form filed and when you select the form field it will clear the default value. The result though is if a user submits the form without changing the default value, I need to see if it exist in addition to my normal string sanitations
In this snippet below of PHP I need to run 2 conditions on $fname but below will not work, can someone help please
$fname = 'first name';
if (trim($fname) == '') && ($fname != 'first name') {
$err .= "error";
}else{
$err .= "all good";
}
For karim79
this code below from your example, exactly like this gives me this error
Fatal Error: Can't use function return value in write context on line 5
<?PHP
$fname = '';
if(empty(trim($fname))) {
echo "First name is empty";
}
?>
$fname = 'first name';
if (trim($fname) == '' || $fname != 'first name') {
$err .= "error";
} else {
$err .= "all good";
}
I would prefer to use strcmp:
if (trim($fname) == '' || strcmp($fname,'first name') !== 0) {
$err .= "error";
} else {
$err .= "all good";
}
If the case of the first name is not important, you should consider using strcasecmp instead. Also note you can use empty to test for the empty string:
$fname = '';
$fname = trim($fname);
if(empty($fname)) {
echo "First name is empty";
} else {
echo "Not empty";
}
When using empty, beware the following (from the manual):
Note: empty() only checks variables as
anything else will result in a parse
error. In other words, the following
will not work: empty(trim($name)).
$fname = 'first name';
if (trim($fname) == '' || $fname == 'first name') {
$err .= "error";
}else{
$err .= "all good";
}
PS: I assumed you want to raise an error if the string is either empty or the standard value. If that's wrong let me know.
I would NOT recommend using empty() for anything. It has some tricky return patterns, including telling you that a 0 is empty, and things of that nature. This, unfortunately, is a shortcoming of PHP.
Instead, try this algorithm (The following assumes your form POSTs):
<?php
$err = array();
// this is for sticklers..with E_STRICT on, PHP
// complains about uninitialized indexes
if( isset($_POST['name']) )
{
$name = trim($_POST['name']);
}
else
{
$name = '';
}
if( strlen($name) == 0 )
{
$err[] = "First name is required.";
}
// after validation is complete....
if( count($err) > 0 )
{
echo "There are errors!";
// probably something more elaborate here, like
// outputting an ordered list to display each error
print_r($err);
}
else
{
echo "It's all good!";
}
?>