PHP improve my show message function - php

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']);
}
}

Related

How to check empty condition using PHP combinations?

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..
}
}

Switch statement doesn't gives out the cases I want

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";
}
}
?>

Php Error with IF statements & validation

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;
}

Nesting if else statements in PHP to validate a URL

I'm currently writing up a function in order to validate a URL by exploding it into different parts and matching those parts with strings I've defined. This is the function I'm using so far:
function validTnet($tnet_url) {
$tnet_2 = "defined2";
$tnet_3 = "defined3";
$tnet_5 = "defined5";
$tnet_7 = "";
if($exp_url[2] == $tnet_2) {
#show true, proceed to next validation
if($exp_url[3] == $tnet_3) {
#true, and next
if($exp_url[5] == $tnet_5) {
#true, and last
if($exp_url[7] == $tnet_7) {
#true, valid
}
}
}
} else {
echo "failed on tnet_2";
}
}
For some reason I'm unable to think of the way to code (or search for the proper term) of how to break out of the if statements that are nested.
What I would like to do check each part of the URL, starting with $tnet_2, and if it fails one of the checks ($tnet_2, $tnet_3, $tnet_5 or $tnet_7), output that it fails, and break out of the if statement. Is there an easy way to accomplish this using some of the code I have already?
Combine all the if conditions
if(
$exp_url[2] == $tnet_2 &&
$exp_url[3] == $tnet_3 &&
$exp_url[5] == $tnet_5 &&
$exp_url[7] == $tnet_7
) {
//true, valid
} else {
echo "failed on tnet_2";
}
$is_valid = true;
foreach (array(2, 3, 5, 7) as $i) {
if ($exp_url[$i] !== ${'tnet_'.$i}) {
$is_valid = false;
break;
}
}
You could do $tnet[$i] if you define those values in an array:
$tnet = array(
2 => "defined2",
3 => "defined3",
5 => "defined5",
7 => ""
);

trying to save time with PHP if/elseif statements

I have a rather big if statement:
if (!$result_spam)
{
$confrim_spam = "FAILED";
}
else if ($result_spam)
{
$confrim_spam = "PASSED";
}
if (!$result_email_manage)
{
$confrim_email_manage = "FAILED";
}
else if ($result_email_manage)
{
$confrim_email_manage = "PASSED";
}
if (!$result_analyt)
{
$confrim_analytics = "FAILED";
}
else if ($result_analyt)
{
$confrim_analytics = "PASSED";
}
Now I want to do another if statement to check if all have PASSED or if all have FAILED or is some have PASSED and some have FAILED and then echo (do something with) the failed ones.
I know how to check if all have passed or failed:
if ($confirm_spam == "PASSED" AND $confirm_analytics == "PASSED"
but to check if some have passed and some haven't and then find the ones that failed will take too long, right?
I was just wondering, would there be an easier/quicker way to do this?
Since they are all bools anyway:
if($result_spam && $result_email_manage && $result_analyt){
//do all passed
}
elseif($result_spam || $result_email_manage || $result_analyt){
//at least one passed
if(!$result_spam){ echo '$result_spam failed';}
if(!$result_email_manage){ echo '$result_email_manage failed';}
if(!$result_analyt){ echo '$result_analyt failed';}
}
else {
//do all failed
}
You can change validation logic to something like
$passed = array();
$failed = array();
if (!$result_spam)
{
array_push($failed, "confirm_spam");
}
else
{
array_push($passed, "confirm_spam");
}
...
Then you have an easy and clear way to check whether all passed/failed and which tests are failed.
What if you try this way:
$passed = $failed = "";
$all = array("confrim_spam" => $result_spam,
"confrim_email_manage" => $result_email_manage,
"confrim_analytics" => $result_analyt);
foreach($all as $a => $b)
{
if (!$b)
$failed.= $a . ", ";
else
$passed.= $a . ", ";
}
Then if var $passed is empty, none passed else if $failed is not empty, at last one have not passed.. so do you got what passed and what failed and do something with them. And you can store results both in a string or an array whatever you want...

Categories