How can i break parent if in PHP?
example this code:
if(true){ // This is parent conditional
if(true) { // This is child conditional
break parent conditinal
}
}
afterBreakDoMe();
From code above. I want when child conditional is true. Then it break parent conditional (exit from that conditional) and continue the rest of the code (afterBreakDoMe()).
Update - Real code
$errorMessage = '';
if(isset($_POST) && count($_POST)) { // Detect some user input
// validation
$countryName = trim($_POST['countryName']);
if($countryName == ''){ // validation user input, if false. exit from parent if and continue show html input (refer to $Render->output())
$errorMessage = 'Name must not be empty!';
}
header('Location: '.$baseUrl.'&page=tableShipping');
}
$Render->setTitle('Create New Country');
$form = $Render->parser('createCountry', array(
'errorMessage' => $errorMessage,
));
$Render->addContent($form);
$Render->output();
You cannot do that (except using goto, which is taboo), and should not do that. Swapping functionality for simplicity is a bad idea.
Based on your "real" code, your program flow doesn't make sense.
if($countryName == ''){ // validation user input, if false. exit from parent if and continue show html input (refer to $Render->output())
So, if it's true, you're going to set $errorMessage, then exit, leave the page, and never use it again? Why? You might as well just forget the error message, call the header(), then call exit;.
I've created the following code based on what I think you want to happen, and commented it as an explanation:
$errorMessage = '';
if(isset($_POST) && count($_POST)) { // Detect some user input
// validation
$countryName = trim($_POST['countryName']);
if($countryName == ''){ // validation user input, if false. exit from parent if and continue show html input (refer to $Render->output())
$errorMessage = 'Name must not be empty!';
} else {
// If there is no error, continue forward.
header('Location: '.$baseUrl.'&page=tableShipping');
exit; // Leave the page execution since you've applied a header.
}
}
// This will only execute if there is an error, since we left the page otherwise.
$Render->setTitle('Create New Country');
$form = $Render->parser('createCountry', array(
'errorMessage' => $errorMessage,
));
$Render->addContent($form);
$Render->output();
All in all, consider the flow of your program in order to determine what happens next, not what to skip.
You could use a variable and an extra if-statement:
$errorMessage = '';
$emptyCountry = false;
if(isset($_POST) && count($_POST)) { // Detect some user input
// validation
$emptyCountry = trim($_POST['countryName']) == '';
if($emptyCountry){ // validation user input, if false.
$errorMessage = 'Name must not be empty!';
}
header('Location: '.$baseUrl.'&page=tableShipping');
}
if (!emptyCountry) {
$Render->setTitle('Create New Country');
$form = $Render->parser('createCountry', array(
'errorMessage' => $errorMessage,
));
$Render->addContent($form);
}
$Render->output();
Simple
if (true) {
if (true) {
// Do stuff
// It will then break automaticly
// but if the condition here is false you got the else ;)
} else {
}
}
Use goto. This is used for jumping in code
Now that I can read the real code sample I think what you need to do is simple put all the conditionals together in a single. Using goto will get the job done but can easily make you code hard to read and maintain. Perhaps its time to rethink the program flow.
Anyway, what I am saying is something like this:
if(!empty($_POST) && isset($_POST['countryName']) && (trim($_POST['countryName']) == '')){
$errorMessage = 'Name must not be empty!';
}
...
$errorMessage = '';
do {
if(isset($_POST) && count($_POST)) { // Detect some user input
// validation
$countryName = trim($_POST['countryName']);
if($countryName == ''){ // validation user input, if false. exit from parent if and continue show html input (refer to $Render->output())
$errorMessage = 'Name must not be empty!';
break;
}
header('Location: '.$baseUrl.'&page=tableShipping');
}
while(false);// only for break
Related
I am a newbie and trying to implement a simple validation script after reading up, but I can't see how I can have multiple Ifs that will only do an sql insert if all required fields are met. Rather than having the multiple else statements, what is a syntax approach for having all the form validation Ifs together and if one of them fails, then the correct error is shown and the sql is not execute?
if(isset($_POST ['submit'])){
$user_ID = get_current_user_id();
$catErr = $ratingErr = $titleErr = $textErr = "";
if (empty($_POST["category"])) {
$catErr = "Category is required";
} else {
//DO THE INSERT BELOW!
}
if (empty($_POST["rating"])) {
$ratingErr = "Rating is required";
} else {
//DO THE INSERT BELOW!
}
if (empty($_POST["post_name"])) {
$postErr = "Title is required";
} else {
//DO THE INSERT BELOW!
}
if (empty($_POST["text"])) {
$textErr = "Text is required";
} else {
//DO THE INSERT BELOW!
}
//PDO query begins here...
$sql = "INSERT INTO forum(ID,
category,
rating,
post_name,
text
Use one variable for all the error messages and concatenate to it in the branches, so in the end if that variable is still empty string you won't do the insert. (And you don't need any of the empty else blocks that contain nothing but a comment.)
$err = "";
if (empty($_POST["category"])) {
$err .= "<br/>Category is required";
}
if (empty($_POST["rating"])) {
$err .= "<br/>Rating is required";
}
if (empty($_POST["post_name"])) {
$err .= "<br/>Title is required";
}
if (empty($_POST["text"])) {
$err .= "<br/>Text is required";
}
//PDO query begins here...
if($err=='')
{
$sql = "INSERT INTO forum(ID,
category,
rating,
...";
...
}
There are many solutions to your problem. Here are 3 methods of solving your issue.
You could combine all of your if statements like so:
if (empty($_POST['rating']) || empty($_POST'rating']) || ... ) { ... }
and separate them by double pipes.
You could also check the entire array:
if (empty($_POST)) $error = "There was an error!";
You could set a universal error variable and then output it.
A third solution could keep your current syntax but cut down on the amount of lines. You could save lines by doing without brackets. You can create an array and push your errors to the array.
Note: You can use empty() or isset().
// create an array to push errors to
$errors_array = array();
// if a particular field is empty then push the relevant error to the array
if(!isset($_POST['category'])) array_push($errors_array, "Category is required");
if(!isset($_POST['rating'])) array_push($errors_array, "Rating is required");
...
Once you have an array full of errors you can check for them like so:
// if the array is not empty (then there are errors! don't insert!)
if (count($errors_array) > 0) {
// loop through and echo out the errors to the page
for ($i = 0; $i < count($errors_array); $i++) {
echo $errors_array[i];
}
} else {
// success! run your query!
}
You should use javascript to validate the page before it is even processed into a post. This script will run client-side when they hit submit and catch errors before they even leave the page.
Here's a tutorial on how to do something like that: tutorial
Each field can have its own validation parameters and methods, and it will also make the page's code look a lot nicer.
I got it to go with this approach after showdev got me thinking that way. It's not very elegant perhaps, but does the trick, although all the user is taken to a blank page if there are errors and it simple says: Missing category (or whatever). Wondering if I can echo a link or something back to the page with the form from there so the user has an option like "go back and resubmit". Otherwise I will have to handle and display the errors alongside the form which will require a different approach altogether...
if(isset($_POST ['submit'])){
$errors = false;
if(empty($_POST['category'])) {
echo 'Missing category.<br>';
$errors = true;
}
if(empty($_POST['rating'])) {
echo 'Missing rating.<br>';
$errors = true;
}
if(empty($_POST['post_name'])) {
echo 'Missing title.<br>';
$errors = true;
}
if(empty($_POST['text'])) {
echo 'Missing text.<br>';
$errors = true;
}
if($errors) {
exit;
}
// THEN ADD CODE HERE. But how display form again if user makes errors and sees nothing but error message on page if they miss something (which is how it works now)
Generally, if you find yourself repeatedly writing very similar statements, using some sort of loop is probably a better way to go about it. I think what you said about "handling and displaying the errors alongside the form" is really what you need to do if you want the process to be user-friendly. If you put your validation script at the top of the file that has your form in it, then you can just have the form submit to itself (action=""). If the submission is successful, you can redirect the user elsewhere, and if not, they will see the form again, with error messages in useful places.
if (isset($_POST['submit'])) {
// define your required fields and create an array to hold errors
$required = array('category', 'rating', 'post_name', 'text');
$errors = array();
// loop over the required fields array and verify their non-emptiness
foreach ($required as $field) {
// Use empty rather than isset here. isset only checks that the
// variable exists and is not null, so blank entries can pass.
if (empty($_POST[$field])) {
$errors[$field] = "$field is required";
}
}
if (empty($errors)) {
// insert the record; redirect to a success page (or wherever)
}
}
// Display the form, showing errors from the $errors array next to the
// corresponding inputs
I'm working on a Captcha class and i'm almost done, there is one thing that doesn't work
In the file where I put the form, I start with this line:
include 'captcha.php';
$captcha = Captcha::tryCaptcha(2,4,'#000', '#ffffff');
and this is the captch construct:
static $do_generate = TRUE;
function __construct($aantal_letters = 2, $aantal_cijfers = 4, $voorgrond = '#000000', $achtergond = '#ffffff') {
session_start();
if (self::$do_generate == TRUE) {
$letters = substr(str_shuffle('ABCDEGHJKLMNPQRSTUVWXYZ'),0 ,$aantal_letters);
$cijfers = substr(str_shuffle('23456789'),0 ,$aantal_cijfers);
$imgbreed = 18 * ($aantal_letters + $aantal_cijfers);
$_SESSION['imgbreed'] = $imgbreed;
$_SESSION['captcha'] = $letters . $cijfers;
$_SESSION['voorgrond'] = $this->hex2rgb($voorgrond);
$_SESSION['achtergond'] = $this->hex2rgb($achtergond);
}
}
so in other words I put my stuff in a session if the static var $do_generate == TRUE
So when I post the form, the captcha is getting checked by a procesor.php
like this:
if (Captcha::captcha_uitkomst() == TRUE) {
echo "Great";
} else {
echo "Wrong";
}
And this is the captcha function that checks the etered captcha code:
static function captcha_uitkomst() {
if (strcmp($_SESSION['captcha'], strtoupper(str_replace(' ', '', $_POST['captcha-invoer']))) == 0) {
return TRUE;
} else {
echo "test";
self::$do_generate = FALSE;
return FALSE;
}
}
If I enter a correct captcha code, it's all good, that works I get the echo great.
If wrong I get the echo Wrong,
Perfect, but.... when I go back to form (hit backspace one history back) to enter a correct captcha, it regenerates a new captcha.
In the class: captcha_uitkomst you see that I made the self::do_generate FALSE
And the echo 'TEST' works when it's false, (just for checking)
What am I doing wrong
When you hit "back", the page is reloaded. You get a new CAPTCHA.
The premise of your question is fundamentally flawed, as you have just randomly assumed that this shouldn't happen, whereas in reality this is entirely by design.
It wouldn't be a very effective CAPTCHA if you could repeatedly get it wrong then go back and try again; any bot could just start brute forcing it and learning from the experience.
I am trying to wrap up this contact/quote form which has same page validation but external processing. I have set up a variable to go in the form action and the variable/url changes from the same page to the processing page when the form validates. However, it is taking two clicks on the submit button to process the form after all the required fields have been filled in: All the required fields will be filled in, I click submit, the page reloads with the saved data variables and then when I hit submit agin, it finally goes through, sending the email and loading the thankyou page. I have searched the posts here and tried multiple things but have not found a solution. I am definitely not a php expert, still a newbie so this may not be the best way to accomplish this but I'd appreciate any ideas on how to finish this up. Here is what I have:
<?php
....
if (empty($Name) && empty($Company) && empty($Address1) && empty($City) && empty($State) && empty($Phone))
{
echo '<p class="tan">The fields marked with an * are required.</p>';
$Process = 'samepageurl';
}
/*else if (empty($Name) || is_numeric($Name))
{
echo '<p class="tan"><b>Please enter your name.</b></p>';
}*/
else if (empty($Company) || is_numeric($Company))
{
echo '<p class="tan"><b>Please enter your company name.</b></p>';
$Process = 'samepageurl';
}
else if (empty($Address1) || is_numeric($Address1))
{
echo '<p class="tan"><b>Please enter your address.</b></p>';
$Process = 'samepageurl';
}
else if (empty($City) || is_numeric($City))
{
echo '<p class="tan"><b>Please enter your city.</b></p>';
$Process = 'samepageurl';
}
else if (empty($State) || is_numeric($State))
{
echo '<p class="tan"><b>Please enter your state.</b></p>';
$Process = 'samepageurl';
}
else if (empty($Phone) || ctype_alpha($Phone))
{
echo '<p class="tan"><b>Please enter your phone number.</b></p>';
$Process = 'samepageurl';
}
else if (strlen($Phone) < 10 || strlen($Phone) > 12 || ctype_alpha($Phone) || ctype_space($Phone))
{
echo '<p class="tan"><b>Please enter a phone number with an area code.</b></p>';
$Process = 'samepageurl';
}
else if (isset($Name) && isset($Company) && isset($Address1) && isset($City) && isset($State) && isset($Phone))
{
$Process = 'processingurl';
}
?>
<form action="<?php echo $Process; ?>" method="post" class="print" >
<p><input type="hidden" name="recipient" value="responses#url.com"/>
<input type="hidden" name="subject" value="Web Site Response"/>
<input type="hidden" name="redirect" value="thankyou.html"/></p>
... form fields ...
</form>
Thank you in advance!
First check for missing variables, then extract and validate the variables, then serve content based on them.
<?php
function verifyPostContains(&$req) {
global $_POST;
$missing = array();
foreach($req as $var => $_) {
if(!isset($_POST[$var])) {
$missing[] = $var;
}
}
return $missing;
}
$requirements = array('name'=>'','city'=>'','state'=>'',...);
$missing = verifyPostContains($requirements);
if(count($missing)>0) {
$content = formErrorReport($missing);
sendHeaders();
echo $content;
exit();
}
// extract, making sure to sanitize
$name = sanitize($_POST["name"]);
...
$errorHtml = array();
// validate by reference. Effectively call testName($name).
if(failsValidation($name, "testName")) {
$errorHtml [] = generateError(NAME_ERROR, $name);
} else { $requirements["name"] = $name; }
if(failsValidation($city, "testCity")) {
$errorHtml [] = generateError(CITY_ERROR, $city);
} else { $requirements["city"] = $name; }
...
if(count($errorHTML)>0) {
generateErrorPage($requirements, $missing, $errorHTML);
} else { processForm($requirements); }
?>
this code assumes you have functions to do the various bits that need to be done, and has some string constants for generating error HTML.
As a newcomer you may want to google for some tutorials that explain doing form processing using PHP at the server, and JavaScript at the client. If you find a tutorial that gives you code that echos errors while it's testing the data, such as you code does, move along. It's not a good tutorial. If you find one that stops after it finds one error, move along too. If you find one that tells you to make sure the values are right in JavaScript, and then says "we already validated this at the client so we use the values directly in PHP", move along, too. Look for a tutorial that explains:
ensuring there's data in all the form fields, using JavaScript, so the submit button is disabled until there's data for all the fields.
ensuring the data matches your criteria, in PHP, so that people who just POST to your server without ever using your page don't get away with injecting all manner of fun stuff they weren't supposed to be able to do
you generate a page with all the errors explained, if there are any, and the form repopulated with the wrong data, but highlighted as wrong
you process the post request if there are no errors.
(Bonus points if the tutorial explains that a POST request is not required to actually ever generate page content as a response, other than a header that indicates whether or not the POST call was accepted or rejected.)
if($getstatus->num_rows != 0 && $getstatusarr = $getstatus->fetch_assoc() && $getstatusarr["Type"] != $data["type"])
echo "error"
else
...
first code will not work, to make works this way, see Nin's post
Is it possible to make the code easily?
Also I can do it like this:
if($getstatus->num_rows != 0)
$getstatusarr = $getstatus->fetch_assoc();
if($getstatusarr["Type"] != $data["type"]) {
echo "error"
$error = true;
}
if(!$error) {
...
}
by ellipsis I have too many lines of code :)
added:
also I can do in this way:
if($getstatus->num_rows != 0) {
$getstatusarr = $getstatus->fetch_assoc();
if($getstatusarr["Type"] != $data["type"]) {
echo "error";
goto skip;
}
}
... // some code which I need not to execute if $getstatusarr["Type"] != $data["type"] are true
skip:
// another code which will execute in all cases
Well, don't use goto: :)
Whether you put all the if's on one line or on several lines is mostly a personal preference.
Too many lines with if will make the code harder to read but putting it all on one line also makes it difficult to read and difficult to debug (error on line 12 can mean many things then). If you're using a debugger like xdebug or Zend debug then having multiple lines to step over is also easier.
So find a way in between this.
I would do it like this, since then you also check if fetch_assoc() returned a result:
if($getstatus->num_rows != 0 && $getstatusarr = $getstatus->fetch_assoc())
if($getstatusarr["Type"] != $data["type"]) {
echo "error"
$error = true;
}
if(!$error) {
...
}
From my point of view is always best to unwrap statements and clean the code as much as you can, maybe someone later on will have to read what you did and he will have a hard time doing that.
Also you cannot assign new variables in a if statement like that:
$error = false;
if($getstatus->num_rows)
$getstatusarr = $getstatus->fetch_assoc();
if($getstatusarr["Type"] != $data["type"]) {
$error = array('type' => 'invalid type');
}
}
if($error) {
// do something with $error array
}
I don't know where I am going wrong in else if logic...
I want to validate this signup script in 3 steps:
1st: check if any field is empty, in which case include errorreg.php and register.php.
2nd: If email already exists include register.php.
3rd: If all goes well insert data to the database.
<?php
$address =$_POST["add"];
$password =$_POST["pw"];
$firstname =$_POST["fname"];
$lastname =$_POST["lname"];
$email =$_POST["email"];
$contact =$_POST["cno"];
$con=mysql_connect("localhost","root","");
mysql_select_db("bookstore");
$q2=mysql_query("select * from customer where email='$email'");
$b=mysql_fetch_row($q2);
$em=$b[0];
if($password != $_POST['pwr'] || !$_POST['email'] || !$_POST["cno"] || !$_POST["fname"] || !$_POST["lname"] || !$_POST["add"])
{
include 'errorreg.php';
include 'register.php';
}
else if($em==$email)
{
echo 'email already present try another';
include 'register.php';
}
else
{
$con=mysql_connect("localhost","root","");
mysql_select_db("bookstore");
$q1=mysql_query("insert into customer values('$email','$password','$firstname','$lastname','$address',$contact)");
echo 'query completed';
$q2=mysql_query("select * from customer where email='$email'");
$a=mysql_fetch_row($q2);
print "<table border =2px solid red> <tr><th>id </th></tr>";
print "<td>$a[0]</td>";
print "</table>";
include 'sucessreg.php';
echo " <a href='newhome.php'>goto homepage</a>";
}
?>
There's a lot to correct here, but to your specific concern, that the "loop" doesn't go on to the second and third "steps", that's because you're thinking about this wrong. In an if/else if/else code block, only one of the blocks is executed at a time, the others are not. For instance, if a user submitted a number, we could tell them it was even or odd with the following:
if($_GET['number'] % 2 == 0){
echo "That's even!";
} else {
echo "That's odd!";
}
You are attempting to do one check, then another, then a third. In this case, you want to nest your conditionals (if statements) rather than have them come one after another, like so:
if(/* first, basic sanity check*/) {
if(/* second, more complex check */) {
if(/* final check */) {
// Database update
} else {
// Failed final check
}
} else {
// Failed second check
}
} else {
// Failed basic check
}
Some other comments on your code:
Pay attention to formatting - laying out your code in consistent and visually clear patterns will help make it easier to see when you make a mistake.
Use isset($_POST['variable']) before using $_POST['variable'], otherwise you'll get errors. One idea is to use lines like: $address = isset($_POST['address']) ? $_POST["add"] : ''; - if you don't know that notation, it lets you set $address to either the value from the $_POST array or '' if it's not set.
Use the variables you created, like $email and $contact, rather than re-calling the $_POST variables - they're clearer, shorter variable names.
Use the better MySQLi library, rather than the MySQL library.
Create one connection ($con = ...) to your database at the beginning of your script, and don't create a second one later on, like you do here.
Explicitly specify which connection your queries are running against - you say $q2=mysql_query("SELECT ...") but you should also pass the connection you've constructed,
$q2=mysql_query("SELECT ...",$con).
First of all you want to check if the property isset in your $_POST object:
if(isset($_POST["name"])
second you want to check if the value set is empty
if(isset($_POST["name"] && !empty($_POST["name"]))
now you just have to scale it up to check all your properties it would be handy to move it into a function like this
function ispostset($post_var)
{
if (isset($_POST[$post_var]))
{
if ($_POST[$post_var] != '')
{
return true;
}
else
return false;
}
else
return false;
}