form validation using form from include () file

Ask about general coding issues or problems here.

Moderators: egami, macek, gesf

Post Reply
guvna
New php-forum User
New php-forum User
Posts: 15
Joined: Fri Mar 10, 2017 7:42 am

Tue Mar 12, 2019 4:07 am

I've been researching looking into form method and post but can't seem to get round this one. Whilst this is a good example:
https://www.w3schools.com/php/php_form_complete.asp The form is self contained.

My situation is twofold but I'll deal with the validation while using an include file first.

My form, as a self contained page, works fine for validation of fields and captcha. When I publish to the live website, the form page is called with an include() function so my form page is as follows:

/frm/frm-pm.php
include ('../header.php');
include ('../retail/pm_form.php');

pm_form.php is the file that work fine in testing when form action="pm_form.php").

When I run frm-pm.php and click the submit button with field input empty or deliberate errors pm_form.php loads displaying the errors. I'm losing the header/footer, my include()'s.

I tried changing the form action to frm-pm.php but that just generates a 404 error message.

I tried using <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>"> and this is the same result as using pm_form.php.

So before I resort to running the form on a page that isn't loaded using an include() function I just wondered if there is a php method to validate my form where it is being displayed on a webpage through the include() function. All help and advice would be greatly appreciated.

User avatar
hyper
php-forum Fan User
php-forum Fan User
Posts: 839
Joined: Mon Feb 22, 2016 5:52 pm

Tue Mar 12, 2019 8:46 am

Your path is wrong, which is why the file can't be found.

I use $_SERVER['DOCUMENT_ROOT']:

Code: Select all

$root=$_SERVER['DOCUMENT_ROOT'];
include "$root/retail/pm_form.php";
Don't bother with $_SERVER["PHP_SELF"], just use $root and set the rest of the path:

Code: Select all

"$root/frm/frm-pm.php";
Warning: PHP doesn't guarantee the availability of the variable, but I haven't found a server where it hasn't worked; so use with confidence.

guvna
New php-forum User
New php-forum User
Posts: 15
Joined: Fri Mar 10, 2017 7:42 am

Tue Mar 12, 2019 10:52 am

OK so in response to 'hyper' suggestion I've tried a few things.

in public_html/frm
frm-pm.php now shows as:
$root=$_SERVER['DOCUMENT_ROOT'];
include "$root/retail/pm_form.php";

in public_html/retail
pm_form.php
I've no idea why it works but would be nice to get an understanding.
All works with the on page validation ONLY if the form action shows as:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

As soon as the form action gets changed the form fails.

In my old html version I had the follwing:
<form action="mydomainname/frm/mailer-pm.php" method="post">
which displays my 'thank you' page but was done without any form field validation.

So, as mentioned in my first posting, my issue was twofold. The first part has a fix, albeit strangely achieved, so the second part is to get to my 'thank you' page after form validation on submit. My captcha code works and this is the ending of that section:
if ($response->success)
echo "Verification success. Your name is: $fullname";
else
$captchaErr = "Verification failed! Did you confirm you're not a robot?";
echo '<span class="frmErr">' . $captchaErr . '</span>';

Instead of displaying the echo success I'd like to load my 'thank you' page which is located at:
public_html/frm.mailer-pm.php

On the html form page this was the form action but, as I've covered, when the form action is changed from the above my form fails. Again all comments/suggestions will be much apprecoated.

User avatar
hyper
php-forum Fan User
php-forum Fan User
Posts: 839
Joined: Mon Feb 22, 2016 5:52 pm

Tue Mar 12, 2019 1:12 pm

$_SERVER['DOCUMENT_ROOT'] is the full address of your web address from your systems point of view, which is probably to public_html on your system - not all set ups use public_html - by using $_SERVER['DOCUMENT_ROOT'] you can ignore what your path is when developing on one system and then uploading it to your server for public viewing.

It's important to understand the difference between client side and server side, client side is your html web page, all addresses are relative to the document root (web site address) whereas when you are using include, you can include files from anywhere on your computer / server.

For instance, if you have a link on your site

Code: Select all

<a href='/public_html/frm/frm-pm.php'>Click here</a>
you would likely get a 404 and

Code: Select all

<a href='/frm/frm-pm.php'>Click here</a>
would load your page

On my system (Ubuntu), the path to my web root is /var/www/ so I can use:

Code: Select all

include '/var/something_important.php'
but

Code: Select all

<a href='/var/something_important.php'>Click here</a>
would produce an error

Spend a bit of time with a file manager to see what's what and where it is. It will be time well spent and will save you loads of time in the future.

guvna
New php-forum User
New php-forum User
Posts: 15
Joined: Fri Mar 10, 2017 7:42 am

Tue Mar 12, 2019 2:07 pm

Thanks for the direction on the client/server side. Coding is not my principle role so these things take me weeks whereas you may knockout in a few hours. The w3schools link does expalin why
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
works and that part I'm fine with. It's my 2nd part where my mailer-pm.php file would email me the posted results that I'm now stuck on.

Just wondering if there is some straight forward syntax to put to call my mailer-pm.php rather than echo 'successful form submission'.

User avatar
hyper
php-forum Fan User
php-forum Fan User
Posts: 839
Joined: Mon Feb 22, 2016 5:52 pm

Tue Mar 12, 2019 2:42 pm

Include it using the path to the file or replace the echo with the code you want instead.

There is no good reason to use $_SERVER["PHP_SELF"], as I said, learn the directory structure and use $root as shown above, you should already know which file is going to process the form and which files will be needed on success or failure - don't complicate your code or process logic when there isn't any need for it.

guvna
New php-forum User
New php-forum User
Posts: 15
Joined: Fri Mar 10, 2017 7:42 am

Tue Mar 26, 2019 5:27 am

Hyper I have to admit a 'double dunce' here. I should go sit in the corner with the hat on.

First, I was working through a book and stopped at the page going from cookies to sessions. If I'd read the manual I would have understood your replies better!

Second, I used the code you suggested:
"$root/frm/frm-pm.php";
but had used
$root . "frm/frm-pm.php";
I thought if I concatenated them it should work but it didn't.

As I bring this type of coding into new pages with the example:
$root=$_SERVER['DOCUMENT_ROOT'];
in my header file it doesn't pass on to sub pages. Is it normal to have to set again on each page it's being used. For example:
$root=$_SERVER['DOCUMENT_ROOT'];
include ($root . "/includes/myfilename.php");

Or is there some way of defining it just once for reuse over the entire website domain?

User avatar
hyper
php-forum Fan User
php-forum Fan User
Posts: 839
Joined: Mon Feb 22, 2016 5:52 pm

Tue Mar 26, 2019 8:54 am

Hyper I have to admit a 'double dunce' here.
Not at all, we all have to learn, and learning like this is usually a good way, as it sticks.
I thought if I concatenated them it should work but it didn't.
You are missing the slash

Code: Select all

$root . "frm/frm-pm.php";
should be

Code: Select all

$root . "/frm/frm-pm.php";
Getting the address wrong is the cause of many problems.

You can (depending on version of PHP, I think >5.6? which you shouldn't be using anyway) use a constant:

Code: Select all

define('ROOT',$_SERVER['DOCUMENT_ROOT']);
and then use:

Code: Select all

include ROOT . "/includes/myfilename.php";
They just look a bit odd when you start out.

guvna
New php-forum User
New php-forum User
Posts: 15
Joined: Fri Mar 10, 2017 7:42 am

Wed Mar 27, 2019 9:02 am

Okay I'm getting closer. I'll leave the DEFINE for now until I've got the form sorted. I have got my form validating on the correct page (itself) and the recaptcha code works. This only happens when:
<form method="post"> I removed the 'action'.
If I have either of these form action settings the script jumps to the action page bypassing my validation and recaptcha scripts:
1) action="<?php //echo $root . ('/retail/ret_frm_mailer-pm.php');?>"
2) action="ret_frm_mailer-pm.php"

With the 'action' setting removed in my PHP code before the form is closed I have the following:
<?php if (isset($_POST['submit'])) {
followed by my validation and recaptcha code.
I then finish off with code to try and pass the data input to my mailer code to email me the results:
if ($response->success) {
echo "Verification success. Thank you $fullname for your information request."; // to to check code works to this point.
/*
// PHP permanent URL redirection test
header("Location: https://www.rapidtables.com/web/dev/php-redirect.html", true, 301);
exit();
causes error: cannot modify header
*/
/*
// from: https://www.php.net/manual/en/function.header.php
Redirect to a different page in the current directory that was requested
$host = $_SERVER['HTTP_HOST'];
$uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$extra = 'ret_index.php';
header("Location: http://$host$uri/$extra");
exit;
causes error: cannot modify header
*/
/*
// https://stackoverflow.com/questions/271 ... der-method
echo ('
<script type="text/javascript">
window.location.href = ' . $root . '"retail/ret_frm_mailer-pm.php";
</script>');
no error but page doesn't redirect for mailer code.
*/
} else $captchaErr = "Verification failed! Did you confirm you're not a robot?";
echo '<span class="frmErr">' . $captchaErr . '</span>';

My parent page, form page and mailer page are all located in the same directory ($root/retail/). I seem to remember reading that I might need to put the validation code on the 'action' page but wanted to check here first. Hopefully I've expalined myself sufficiently.

I forgot to say that when the form action is defined I do get the email results but there hasn't been any validation so, for example, blank/incorrectly formatted emails will be sent.
Last edited by guvna on Wed Mar 27, 2019 9:09 am, edited 1 time in total.

User avatar
hyper
php-forum Fan User
php-forum Fan User
Posts: 839
Joined: Mon Feb 22, 2016 5:52 pm

Wed Mar 27, 2019 4:41 pm

You're looking at this from the wrong point of view, you are trying to do it in a particular way - don't - you need to do it in the way that it needs to be done.

Do not rely on JavaScript to re-direct, and learn from your mistakes:
hyper wrote:
Tue Mar 26, 2019 8:54 am
I thought if I concatenated them it should work but it didn't.
You are missing the slash

Code: Select all

$root . "frm/frm-pm.php";
should be

Code: Select all

$root . "/frm/frm-pm.php";

Code: Select all

window.location.href = ' . $root . '"retail/ret_frm_mailer-pm.php";
causes error: cannot modify header
This is correct, you cannot modify headers; if you are going to re-direct, you need to do it before you send any output:

Code: Select all

<?php if (isset($_POST['submit'])) {
followed by my validation and recaptcha code.
I then finish off with code to try and pass the data input to my mailer code to email me the results:
if ($response->success) {
echo "Verification success. Thank you $fullname for your information request."; // to to check code works to this point.
header("Location: https://www.rapidtables.com/web/dev/php-redirect.html", true, 301);
exit();

There's nothing wrong with validating in the same page, this is what ifs and includes are for

Code: Select all

if (form validates){
  include $root . '/pages/once/validated/my_page.php';
} else {
  include $root . '/form/needs/correcting/my_page.php';
}

guvna
New php-forum User
New php-forum User
Posts: 15
Joined: Fri Mar 10, 2017 7:42 am

Thu Mar 28, 2019 8:43 am

This is a most valuable point:
"You're looking at this from the wrong point of view, you are trying to do it in a particular way - don't - you need to do it in the way that it needs to be done."

I have been trying to replicate my ancient basic html file to a PHP file with field validation. On submit, this used to send data to the mailer.php file that would email me and then display a 'thank you' page. This is the code of the mailer PHP fle:

<?PHP // ret_frm_mailer-pm.php
$to = "me@mydomainname";
$subject = "Results from your form";
$headers = "From: Form Mailer";
$forward = 1;
$location = "ret_frm-complete.php"; // The Thank you page that previously displayed.
$date = date ("l, F jS, Y");
$time = date ("h:i A");
$msg = "Below is the result of your form. It was submitted on $date at $time.\n\n";

if ($_SERVER['REQUEST_METHOD'] == "POST") {
foreach ($_POST as $key => $value) {
$msg .= ucfirst ($key) ." : ". $value . "\n";
}
} else {
foreach ($_GET as $key => $value) {
$msg .= ucfirst ($key) ." : ". $value . "\n";
}
}
mail($to, $subject, $msg, $headers);
if ($forward == 1) {
header ("Location:$location");
} else {
echo "Thank you for submitting our form. We will get back to you as soon as possible.";
}
?>

When I use the include() function on successful form submit I get the error message:
'Warning: cannot modify header information ....'
in the error message display area on the form page. I'm guessing this is the culprit:
header ("Location:$location");

Is it only possible, in my example, to display messages on the form page on submit as headers have been sent already so I can't open a different 'thank you' page?

So, getting back to what should be done, is my approach correct and I just need to resolve coding issues using a form in the way I am for validation or, should I be using a different approach?

User avatar
hyper
php-forum Fan User
php-forum Fan User
Posts: 839
Joined: Mon Feb 22, 2016 5:52 pm

Thu Mar 28, 2019 12:03 pm

Do all the validation first, and use the logic to decide if to include or re-direct:

Code: Select all

<?php
  if (form_validates){
    header('thank_you_page');
  } else {
    echo 'errors: ';
  }

guvna
New php-forum User
New php-forum User
Posts: 15
Joined: Fri Mar 10, 2017 7:42 am

Tue Apr 02, 2019 2:32 am

I'm pretty sure I'm doing this the way that has been suggested:

if ($response->success) {
//echo "Verification success. Thank you $fullname for your information request.";
header('ret_frm_mailer-pm.php'); // code line 266
} else {
$captchaErr = "Verification failed! Did you confirm you're not a robot?";
echo '<span class="frmErr">' . $captchaErr . '</span>';
}

Forms errors and unsuccessful captha all works fine. On success I get the error:
Warning: Cannot modify header information - headers already sent by (output started at my_server_root/includes/retail_header.inc.php:13) in my_server_root/retail/ret_form.php on line 266.

Line 13 of retail_header.inc.php:
<title><?php echo $page_title; ?></title>

It's the same error whether form action is defined or omitted.

User avatar
hyper
php-forum Fan User
php-forum Fan User
Posts: 839
Joined: Mon Feb 22, 2016 5:52 pm

Tue Apr 02, 2019 8:12 am

You cannot use echo and then header later on.

Do the logic first, then use header or echo depending on the logic.

guvna
New php-forum User
New php-forum User
Posts: 15
Joined: Fri Mar 10, 2017 7:42 am

Thu Apr 04, 2019 3:19 am

OK looks like I'm doomed with this task then. My form logic is correct and works.

My header file has this code in the <head> section for the entire website:
<title><?php echo $page_title; ?></title>

Pages on the website then include the header file and this code:
$page_title = 'My Page Title';

An echo will there appear on every page so no header() function is going to work.

So am I having to redesign my website in order not to get an error message trying to mail myself form information?

User avatar
hyper
php-forum Fan User
php-forum Fan User
Posts: 839
Joined: Mon Feb 22, 2016 5:52 pm

Thu Apr 04, 2019 8:07 am

An echo will there appear on every page so no header() function is going to work.
Correct :D

Lesson learned: if you are going to use header() under certain conditions [filling form out], check for those conditions first and re-direct if necessary, or build page [re show form].

Post Reply