PHP Form processing algorithm - php

By way of partial explanation, my mind-set is strongly procedural, since I've been programming that way since the 60s
I'm working in PHP and trying to get my head around form handling starting with an interactive 404 error form. What I want in minimal pseudo-code is:
do {
OK = true;
display_form;
ask for optional name
ask for optional email address
ask for optional comments
on – submit{
sanitise input
validate input (which could be no input since all is optional)
if one or more inputs invalid set OK = false
}
} while (OK == false)
assemble email to webmaster using $_SERVER superglobals as well as input
send using mail function
Someone "helpfully" added curlies after the while AND at the end -- they really don't belong there -- the idea was that I wanted execution to "drop through" to those two statements only after the DO -- WHILE completed
The mail assembly could be in a separate file, or not
While this is a semi-specific problem, I'm working on the assumption that, if I can get this to work, then getting a database update working will be easier.
It seems to me that my whole conceptual algorithm is incorrect, and until I sort that I'm nowhere. I've been banging at this for a a couple of days – Google pointed at a number of semi-relevant answers here, so I'm giving it a go. The W3C examples clearly show the response code running even when there are problems with the input, which is not what I want.

The main switch you need to make here is probably the one to a request-response model of execution. You can't do a literal do..while, since you will need to send a response back to the client. The next iteration of that will be triggered by a new request to PHP, which begins again from the beginning and doesn't remember any previous state.
So, in pseudo code, it works like this:
if is POST request:
validate input, populate error variables
if input is valid:
send email with data
redirect to different page or display "thanks"
form start
for $field in fields:
output HTML for $field
maybe highlight if error
maybe set value to POSTed value to retain data
form end
So, upon the first page visit, it won't be a POST request and falls straight through to the form part. There won't be any errors or existing data, so the plain form will be output. When the form is submitted, the same code runs again and now enters the if is POST branch. If any values are invalid, it will fall through to the form again, which now can also output any error messages and existing submitted values. Only when all values are valid, will the server send an email and exit this "loop" by redirecting to another page, or maybe just outputting a "Thank you" note.
If you properly separate that into an MVC architecture, you'd have these components:
Model
data validation
email sending
View
outputs the form HTML
Controller
one for handling GET requests, just invoking the view
one for handling POST requests, essentially doing:
errors = model.validate(data)
if no errors:
model.send_email(data)
redirect()
else:
view.display_form(data, errors)
some form of router invoking the right controller based on the request URL and method
These could all be separate functions, or classes, or methods, or just files.

Below is the final code for the page. It's a basic 404 error page that may be of use to someone. And it should answer the requests that I supply the code that I was working with
It includes three files that I've not supplied:
top.php and footer.php and functions.php
top produces the HTML head statements including meta codes and also including top level banners and menu, as well as establishing the basic page format.
footer-- using the server superglobal just before the footer include, the page can provide a code update date for the page. And a consistent name and registration number for our organisation
functions.php supplies a bunch of reused functions. There are a couple of little (fairly obvious) functions in used in this code:
spacer outputs code to create an empty cell in a table.
spanCol creates a column spanning cell in a table, with the specified text and
specified tag open and close
The full page is at http://www.vfmc.org.au/notfound.php -- please don't send me too much junk email.
Code for the guts is here - I don't claim that it's brilliant, but it works thanks to help from here:
<?php
$pageTitle = "File Not Found";
$authorName = "Don Gingrich";
$styleSheet = "./css/mainstyle.css";
include_once 'top.php';
require_once "functions.php";
$indicesServer = array(
'PHP_SELF',
'HTTP_REFERER',
'SCRIPT_FILENAME',
'SCRIPT_NAME',
'REQUEST_URI',
'ORIG_PATH_INFO'
);
if (isset($_SERVER['HTTP_REFERER'])) {
$refering = $_SERVER['HTTP_REFERER'];
} else {
$refering = NULL;
}
$requested = $_SERVER['REQUEST_URI'];
// $refering = $_SERVER['HTTP_REFERER'];
if ($refering == NULL || $refering == " ") {
$refering = "referrer field was blank\n - may be due to mis-typing address\n";
}
/* basic "sanitise input" function */
function test_input($data)
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
function send_webmaster_email($name, $email, $comment, $requested, $refering)
{
global $sent;
$subject = "File not Found: $requested";
$txt = "Trying to access $requested from $refering\n" . "Visitor comments follow:\n" . $comment;
if ($name != "") {
$txt .= "\n\tReporting person's name is: $name\n";
}
if ($email != "") {
$txt .= "\n\tReporting person's email is: $email\n";
}
$to = "webmaster#vfmc.org.au";
$additional_headers = "From: webmaster#vfmc.org.au\r\n";
mail($to, $subject, $txt, $additional_headers);
$sent = true;
}
// define variables and set to empty values
$nameErr = $emailErr = "";
$name = $email = $comment = "";
$myError = false;
global $sent;
$sent = false;
/********************************************************
* Processing code follows -- Only executed after POST
*
*******************************************************/
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$requested = $_POST['requested'];
$refering = $_POST['refering'];
$requested = test_input($requested);
$refering = test_input($refering);
$myError = false;
if ($_POST["button"] == "Submit") {
if (empty($_POST["name"])) {
$name = "";
} else {
$name = test_input($_POST["name"]);
// check if name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z -]*$/", $name)) {
$myError = true;
$nameErr = "Only letters, hyphen, and white space allowed";
}
}
if (empty($_POST["email"])) {
$email = "";
} else {
$email = test_input($_POST["email"]);
// check if e-mail address is well-formed
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$myError = true;
$emailErr = "Invalid email format";
}
}
if (empty($_POST["comments"])) {
$comment = "";
} else {
$comment = test_input($_POST["comments"]);
}
if ($myError == false) {
send_webmaster_email($name, $email, $comment, $requested, $refering);
}
}
}
echo "\n";
echo "<h2>File Not Found</h2>\n";
echo "<br>\n";
echo "<br>\n";
if ($sent == true ){
echo "<h5>Email sent to Webmaster, Thank you</h5>\n";
echo "<br>Use the menu to the left or the back button<br>\n";
echo "to return to the VFMC site<br>\n";
} else {
echo " Unfortunately the file that you have asked for is unavailable.\n";
echo "<br>\n";
echo "<br>\n";
echo "This may mean that the Webmaster has forgotten to load it or the link to it is broken in some way.<br>\n";
echo "Or, if you typed a page in the browser address bar, you may have mis-typed, remember that everything<br>\n";
echo "after the <b>www.vfmc.org.au/</b> is CaSeSensitive -- FiresideFiddlers, is spelled as written.<br>\n";
echo " <br>\n";
echo " <br>\n";
echo "<h6>Please tell the webmaster by sending a message:</h6>\n";
echo " <br>\n";
echo " <br>\n";
$myFile = htmlspecialchars($_SERVER['PHP_SELF']);
echo " <form action= \"$myFile\" method=\"post\">\n";
echo "<input type=\"hidden\" name=\"refering\" value=\"$refering\" />\n";
echo "<input type=\"hidden\" name=\"requested\" value=\"$requested\" />\n";
echo " <table border=\"0\" cellpadding=\"8\" cellspacing=\"8\">\n";
echo " <colgroup>\n";
echo " <col width = auto>\n";
echo " <col width = auto>\n";
echo " <col width = auto>\n";
echo " </colgroup>\n";
echo " <tr>\n";
spanCol("3", "Your name and email address are optional,<br> but the webmaster will be unable to respond <br>directly without them", "h5");
echo " <tr>\n";
echo " <td><label for=\"tswname\">Name</label>:</td>\n";
echo " <td><input type=\"text\" name=\"name\" id=\"tswname\" size=\"25\" /></td>\n";
echo " <td>\t";
if ($nameErr == "") {
echo "(Optional)\n";
} else {
echo "<span class=\"error\">*" . $nameErr . "</span>\n";
}
echo "</td></tr>\n";
echo " <tr>\n";
echo " <td>\n";
echo " <label for=\"tswemail\">Email address</label>:</td>\n";
echo " <td>\n";
echo " <input type=\"text\" id=\"tswemail\" name=\"email\" size=\"25\" />\n";
echo " </td>\n";
echo " <td>\n";
if ($emailErr == "") {
echo "(Optional)\n";
} else {
echo "<span class=\"error\">*" . $emailErr . "</span>\n";
}
echo "</td></tr>\n";
echo " <tr>\n";
echo " <td>\n";
echo " <label for=\"tswcomments\">Comments</label></td>\n";
echo " <td colspan=\"2\">\n";
echo " <textarea rows=\"15\" cols=\"45\" name=\"comments\" id=\"tswcomments\"></textarea>\n";
echo " </td>\n";
echo " </tr>\n";
echo " <tr>\n";
echo " <td align=\"center\" colspan=\"2\">\n";
echo " <input type=\"submit\" name=\"button\" value=\"Submit\" /><br>\n";
echo " </td>\n";
echo " </tr>\n";
echo " </table>\n";
echo " </form>\n";
}
echo " <br>\n";
echo " <br>\n";
echo " <br>\n";
echo " <br>\n";
echo "</td>\n";
echo "</tr>\n";
$filename = $_SERVER['SCRIPT_NAME'];
require_once "footer-code.php";
?>
</tbody>
</table> <!--PWK-EDIT END FOOTER-->
</body>
</html>

Related

PHP send form to email - display content on next page

I'm having some issues with getting the form content sent to email and saved to a session and then displayed on next page.
I have form on contact.shtml which action takes it to mail.php and when content are sent goes to thank_you.shtml.
I need the content shown on the thank_you -page.
All my pages are *.shtml - are this an disadvantage for this?
Codesnippets:
mail.php
$name = $_POST['name'];
$_SESSION['name'] = $name;
$email = $_POST['email'];
$_SESSION['email'] = $email;
$phone = $_POST['phone'];
$_SESSION['phone'] = $phone;
thank_you:
<?php
echo "Navn:" . "$_SESSION['name']";
echo "Email:" . "$_SESSION['email']";
echo "Telefon:" . "$_SESSION['phone']";
?>
I have the obvious on page thank_you and mail.php.
<?php
session_start();
?>
Beside these few lines i have several more with text input and also image files for which i want to show the filename and extensions and also a small preview.
Am i missing something or on the complete wrong track?
You could bypass using a session. While I like separation of concerns the following outline 'all-in-one' solution would satisfy your problem:
<?php
$email = null;
$sent = false;
$error = null;
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$email = isset($_POST['email']) ? $_POST['email'] : null;
if($email && filter_var($email, FILTER_VALIDATE_EMAIL)) {
// supplied email looks good, send email here.
$sent = true;
} else {
$error = 'Please enter a valid email address.';
}
}
?>
html goes here..
<?php if($sent) {
echo 'Thankyou. The email you supplied is: ' . htmlspecialchars($email);
?>
<?php } else { ?>
<?php echo $error ? '<p>' . $error . '</p>' : ''; ?>
<form method="POST">
Email:
<input type="text" name="email" value="<?php echo htmlspecialchars($email) ?>">
<input type="submit">
</form>
<?php } ?>
If a valid email is posted, you can then trigger your mail out.
Do you really need to display the gathered user data?
<?php
echo "Navn:" . htmlentities($_SESSION['name']);
echo "Email:" . htmlentities($_SESSION['email']);
echo "Telefon:" . htmlentities($_SESSION['phone']);
?>
You have to remove the quotes around the variables. Use htmlentities to convert all applicable characters to HTML entities

PHP - Passing variables

In PHP I have this code in a function
ob_start();
echo "<p>Your Feed URL - <a href='/blah'>Click Here</a></p>";
$feedURL = ob_get_contents();
ob_end_clean();
Now this stores my ECHO as a local variable called $feedURL, I need to use this variable in another part of my PHP script. The echo statement is generated each time I post a form. What I need is when a form is POSTed, the variable created can then be used in another part of the script within a function.
I have tried using return $var;
When I then tried echo $var in a seperate function it returned an empty string?
Am I being stupid or is there something I'm missing?
I want to use the variable in this other function.
function add_page_content_Send_Feed(){
echo "<h2>Send your feed via email</h2>";
echo "<p>Below you can send your feed URL. Just enter the email you wish to send to.</p>";
echo "<p>This email will contain the URL leading to your feed</p>";
echo "<form id='post' action='http://localhost/wp/ultrait/admin.php?page=page6' method='POST'>";
echo "<label for='email'>Email:</label> <br /> <input type ='text' value = '' name = 'email' id = 'email'/><br /><br />";
echo "<input type='submit' name='send_feed' value='Send my feed' id='submit'/>";
echo "</form>";
// Example using the array form of $headers
// assumes $to, $subject, $message have already been defined earlier...
$headers[] = 'From: UltraIT <demo#ultrait.org>';
$subject = 'Feed URL from UltraIT Property Management';
$test = "blah";
$message = 'Hello, please see your feed URL below. ' . $test;
if(isset($_POST['send_feed'])){
if(empty($_POST['email'])) // If no email has been specified
{
echo "<p>Please enter an Email</p>";
}
else{
$email = $_POST['email'];
print ($email);
}
$to = $email;
wp_mail( $to, $subject, $message, $headers);
}
}
I need the variable to be the value of the $message variable.
To access it from any function you can use global keyword, but its not a good practice, use function param to keep your code loose coupled.
function myFunc() {
global $feedURL;
//then use it
}
make sure you have included above file on top.
Update
you need to pass $feedURL as argument in you function
add_page_content_Send_Feed($feedURL) {
...
$message = 'Hello, please see your feed URL below. ' . $feedURL;
...
}

PHP echo printing language construct

In an assignment I'm having trouble running a php script with page handling. It's outputting actual php code when submitted through another php page but works fine on its own.
I have a html login page which submits via submit buttons rather than form submit [a requirement]. This submits to login.php.
Seperately I have testBalance.php which checks a file balance.txt on my server which simply has an amount (1000). testBalance.php calls a function in getBalance.php to return the amount here.
THE PROBLEM IS when I run testBalance.php by itself it works just fine. Displaying "Account Balance: 1000.00" but when I attempt to set (in login.php) testBalance.php as the redirect url, the page literally displays code from my testBalance.php page: "Account balance: "); printf ( "%01.2f", $returnValue ); echo ("
"); ?> " I know it's convoluted, this is an intro to php portion of an web prog. class. I'm guessing it has to do with the value pairs that are being passed through to the pages. Can anyone help?
LOGIN.HTML snippit
<input type="button" name="sub_but" id="bal" value="check balance"
onclick="location.href = 'login.php' + '?' + 'name='+ document.forms[0].username.value +
'&redirectURL=' + 'bal';" />
LOGIN.PHP
<?php
$NAME=$_GET["name"];
$PAGE=$_GET["redirectURL"];
$DESTINATION="";
if ($NAME == ''){ /* HANDLES NAME ERRORS */
echo "PLEASE RETURN AND ENTER A NAME.";
}
elseif (ctype_alpha(str_replace(' ', '', $NAME)) === false) {
echo "$NAME is not a valid name. Name must contain letters and spaces only";
}
else{
if($PAGE=='with'){
$DESTINATION = "withdraw.html";
}
elseif($PAGE=='bal'){
//$DESTINATION = "balance.html";
$DESTINATION = "testBalance.php";
}
elseif($PAGE=='depos'){
$DESTINATION = "deposit.html";
}
elseif($PAGE=='weath'){
$DESTINATION = "weather.html";
}
elseif($PAGE=='xchang'){
$DESTINATION = "currency.html";
}
/*echo("$DESTINATION\r\n");*/
header("Content-Length: " .
strlen(file_get_contents($DESTINATION)));
header("Cache-Control: no-cache");
readfile($DESTINATION);
}
?>
testBalance.php body snippit
<?php
include 'getBalance.php';
$returnValue = readBalance();
echo "<p>Account balance: ";
printf( "%01.2f", $returnValue );
echo "</p>";
?>
getBalance.php
<?php
function readBalance(){
$file = "balance.txt";
$fp = fopen($file, "r");
if (!$fp){
echo "<p>Could not open the data file.</p>";
$balance = 0;
}
else{
$balance = fgets($fp);
fclose ($fp);
}
return $balance;
}
?>
readfile() doesn't EXECUTE anything it reads. It's literally just slurping in the file's bytes and spitting them out to the client. It's basically doing
echo file_get_contents(...);
If you want your other files to be executed, you need to include() or require() them instead. Or you could try eval(), but you really don't want to go down that route. eval() is evil and dangerous.

PHP function get checkboxes value

I'm currently creating a website for a local sports union, so far I have created numerous pages, one of them being a table with the members and their information. Each member has a checkbox that contains the email address as a value. I should add that at the moment the members information is viewed in members.php, but the file that gets the information (The code you can see below) is from backend file fetch.php.
What I want is that when you check multiple checkboxes and press 'Send Mail', it should open a mailto:?bcc=mail1,mail2 etc.
if(mysqli_num_rows($result))
{
echo "<form method=\"post\">";
// Printing user information etc.
echo "<td><input name=\"email[]\" type=\"checkbox\" class=\"email-cb\" value=\"$email\"></td>";
echo "<tr><td><input type=\"submit\" value=\"Send Mail\"></td></tr>";
echo "</form>"
}
First of when you press the submit button (Or Send Mail if you like), it should simply do Send Mail
I have been working on this for a while and can't seem to find a solution, anyways I came up with this method to atleast extract emails (I think this is correct).
if(isset($_POST['email']) && is_array($_POST['email']))
{
foreach($_POST['email'] as $email)
{
$emailList = "mailto:?bcc=" . implode(',', $_POST['email']);
}
}
Change $_POST['fruit'] to $_POST['email'], and you don't need the loop, because the post data is already an array.:
if(isset($_POST['email']) && is_array($_POST['email']))
{
$emailList = "mailto:?bcc=" . implode(',', $_POST['email']);
}
What does $_POST['fruit']?? Maybe you are looking for this:
if(isset($_POST['email']) && is_array($_POST['email']))
{
foreach($_POST['email'] as $email)
{
$bccList .= $email.',';
}
$emailList = "mailto:?bcc=" . $bccList;
}

HTML Form Not Outputting To CSV File (Or Displaying Correct Error Messages)

I'm having trouble creating a form that exports to a .CSV file in PHP. I created a fiddle for the HTML which is here:
http://jsfiddle.net/tqs6g/
I'm coding in PHP so I can't really show the full code on JSFiddle since it can't support the PHP but here's my PHP code:
<?php
if($_POST['formSubmit'] == "Submit")
{
$errorMessage = "";
if(empty($_POST['brandname']))
{
$errorMessage .= "<li>Please enter a business/brand name.</li>";
}
if(empty($_POST['firstname']))
{
$errorMessage .= "<li>Please enter your first name.</li>";
}
$varBrand = $_POST['brandname'];
$varFName = $_POST['firstname'];
$varLName = $_POST['lastname'];
$varEmail = $_POST['email'];
$varSite = $_POST['website'];
if(empty($errorMessage))
{
$fs = fopen("mydata.csv","a");
fwrite($fs,$varBrand . ", " . $varFName . ", " . $varLName . ", " . $varEmail . ", " . $varSite . "\n");
fclose($fs);
exit;
}
}
?>
When I click Submit it successfully goes to 'thankyou.php' (which is set in the form action) but I can't figure out why it's not posting the correct error messages or filling in my 'mydata.csv' file upon click. Possibly it's a sight syntax error? Let me know if you need any more info, I know this is kind of confusing seeing as the PHP is separated from the Fiddle.
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') { // better method to check for a POSt
... validation stuff ...
$data = array();
$data[] = $_POST['brandname'];
$data[] = $_POST['firstname'];
etc...
if (empty($errrorMessage)) {
$fs = fopen('mydata.csv', 'a') or die("Unable to open file for output");
fputcsv($fs, $data) or die("Unable to write to file");
fclose($fs);
exit();
} else {
echo $errormessage;
}
}
A few things of note:
1) using $_SERVER['REQUEST_METHOD'] to check for submit type is absolutely reliable - that value is always set, and will always be POST if a post is being performed. Checking for a particular form field (e.g. the submit button) is hacky and unreliable.
2) Using fputcsv() to write out to a csv file. PHP will do all the heavy work for you and you jus tprovide the function an array of data to write
3) Note the or die(...) constructs, which check for failures to open/write to the file. Assuming that a file is available/writeable is unreliable and will bite you at some point in the future. When dealing with "external" resources, always have error handling.

Categories