PHP - Smarty Variables unset after header redirect - php

I have a php file (form.php) that uses a template (form.htm) to display a form. The template file's form action is form.php. If the form is incomplete when submitted, I want to redirect back to the form WITHOUT losing information that the user has already input.
I'm setting smarty variables using t->assign('varname', $_POST['var']) and setting the form values to these variables ( value="{$varname}" ), however when redirected using php's header() function, these Smarty variables are lost (which I've confirmed using Smarty {debug}).
Does anyone have any idea of how to make it so that these variables aren't unset when using a header redirect? Thanks!

Smarty is only template engine, so you cannot do here more than in PHP.
But in your case you said you want to make header redirect after sending form (to be honest I have no idea why you want to do it. In normal case you simple set action in form and in controller you simple check data and if they are valid you do what you want - for example send email and if they are not valid you simple show the form again - that's it).
However if you really need to do this that way, what you can do is to use session data and save all data from post to session, make redirection and use that from session to display in Smarty.
So in PHP you can do:
$_SESSION['post_data'] = $_POST;
// now you make redirection
And in file you handle redirection you can simple do:
$smarty->assign('post_data',$SESSION['post_data']);
unset($SESSION['post_data']);
And in template file you can then use:
{$post_data.var}
EDIT
But as I said normally you do it this way in PHP file:
$isValid = false;
if (isset($_POST['submit']) {
$isValid = validateData($_POST);
if ($isValid) {
// do something here - for example send email
}
else {
$smarty->assign('error', 'There were errors in your form. Try again');
}
}
$smarty->assign('is_valid',$isValid);
And in Smarty you do:
{if $isValid}
form was sent
{else}
{if isset($error)}{$error}{/if}
you display form here
{/if}

Don't redirect the user. Just redraw the form. In general, this HTTP workflow should be used when dealing with forms:
GET /form.php - Display the form to the user
POST /form.php - Process the form input
If the form input is invalid, send back form.php
If the form input is valid, save to the database, now redirect the user
So basically you have:
GET
POST (invalid input from the user)
POST (valid input from the user)
REDIRECT

Related

How do I stop people manipulating URLs to submit forms in PHP?

When a user submits any form, a $_GET['variable_name'] is sent by the webpage and will give a URL like the following: www.mywebsite.com/index.php?variable_name_here='yes'.
However people can just write the URL www.mywebsite.com/index.php?variable_name='yes' into the address bar of the website and gain access to this part of the script, without actually submitting the form!
This is a problem! It's breaking specific parts of the script linked to that form submission! This is because the part of the script relating to the $_GET['variable_name'] can't get the variables that should be sent by the form as it is never submitted!
How do I stop people getting to specific parts of a script when they manipulate the URL by sending them back to www.mywebsite.com/index.php?
P.S. : This is for user submitted data through a form which is then processed (no SQL or any alike software involved)
If you are worrying about people getting in to your site without logging in or not having correct params, you should first check to see if the correct $_GET variables exist using isset(). If all paramaters you are expecting exist allow them to pass, otherwise use header('Location: /index.php'); to force a redirect.
To redirect from www.mywebsite.com/index.php?variable_name='yes' to www.mywebsite.com/index.php you would need to include the following code below before you open a HTML header! This solution will work for any $_GET variables within your whole website if you place it within an includes("filename_here"), no need to change the code.
//if there are any $_GET variable(s) set (doesn't matter what the name of the variables are)
if (! empty($_GET))
{
//if there is no record of the previous page viewed on the server
if(! isset($_SERVER['HTTP_REFERER']))
{
//get requested URL by the user
$redir = $_SERVER['PHP_SELF'];
//split parts of the URL by the ?
$redir = explode('?', $redir);
//redirect to the URL before the first ? (this removes all $_GET variables)
header("Location: $redir[0]");
}
}

How would I pass information from one PHP to another?

I need to create a landing page that's dynamic to information picked up by a form that executes a php script.
Person submits form > PHP Code sends me an email > PHP code that displays information
I have a hidden input in every form that identifies what form it is, and depending on what the value or "identification" of the form a specific code on the php is executed using a switch and I thought that maybe I could use that same identifier to execute another switch on the page after that. My problem is I don't know how to carry that value or identifier from one php to the other.
So just to reiterate, I want to know how to move or copy variables from one php to another, after mail() is executed.
Im using $request to get those variables
Keep this source form identifier and render it into your new form identifier field. It will deliver the response form with same identifier
after you do your Mail() thing, call a function that runs whatever you want.
If the classes or functions you want to run are not available you must include or require them.
I'm not 100% sure about what you are asking for, but due the comments I'll make a try to answer it.
When I create forms I usually have one page with the actual form and another page that handles the data. When the data is handled I simply redirect the user back to the form and then give them feedback.
The reasons I'm using two separate pages are the following:
I like to keep the code for the form and the handler separated.
Users can't accidently submit the form again by refreshing the page.
The same handler can be used by eventual Ajax and uphold progressive enhancement.
An extremely simplified example below.
form.php:
<?php
//Start session
session_start();
//If the session variable has been set
if($_SESSION['remember'])
{
## DISPLAY FEEDBACK ##
}
else
{
## DISPLAY FORM ##
}
//Delete the session variable
unset($_SESSION['remember']);
?>
req.form.php
<?php
//Start session
session_start();
//If a form has been submited
if(isset($_POST['submit']))
{
## HANDLE THE DATA ##
//Set a session variable
$_SESSION['remember'] = true;
//Redirect the user back to the form
header('Location: /form.php');
exit;
}
?>

SQL assigning errors to sessions or variables?

I have created Login forms and registration forms for a website.
The form is posted for validation to checklogin.php and checksign.php, however when it finds any errors it displayes them in the separate file.
The following is the error message for the following validation statement
if (!$_POST['fullname'] | !$_POST['myusername'] | !$_POST['mypassword'] | !$_POST['remypassword']) {
die('You did not complete all of the required fields');
}
My question is: how do i show them in the same page? For instance; in a label next to the form. Thanks, any tips would be of great help. this is the website im making autosales
By structuring your code so that the order of validation can come before final processing, and if not, display the form page again
if($_SERVER['REQUEST_METHOD'] === 'POST')
{
$valid = false;
// perform input validations here
if(dosomething())
{
$valid = true;
}
// if valid, perform processing here, and either show success page (or redirect)
if($valid === true)
{
// SQL junk here
include('success.php');
exit();
}
}
// render original form after this line
Your form post data to checklogin.php, instead of that post data to index.php and handle validation on that page.
<form class="clearfix" action="checklogin.php" method="post">
In the past, I've used a custom error handler that uses sessions to store errors, I'd recommend that.
The advantage of using sessions (within a custom error handler) to store errors is that they can easily be read and displayed in whatever view page you have. If you want to throw errors in classes, for instance, you can display them whenever you choose once they've been saved to the session. So while for this particular problem you could simply move all your code to one php file, it's probably not the best solution.
Not to mention that if your "check login" redirects back to the login page, obviously all your variable's values will not persist.

How to show 'success' message on form submit without changing URL?

I have a PHP site (with CodeIgniter) that includes a registration form. I have a page with some details, which links to the form on a separate page. The form posts to a third URL which does the processing and redirects back to the first page if it's successful (or the form page if not).
Currently I am adding a parameter for success: example.com/page?success=1 which shows a success message. The problem is that some people have been sharing this URL (and clicking the Facebook Like button) so when another user opens that URL they see a message "thanks for registering!" which they obviously haven't done yet.
I thought this was the standard way of doing forms (submitting to one URL and redirecting to another) but is there a better way? I don't want to post back to the same page because then you get the POSTDATA warning when trying to reload the page.
You have three ways to do this
The way you're using
Not actually redirecting but sending request(s) with AJAX
SESSION (or, in edge case, cookies)
If you select to use SESSION, you can just assign a session variable to true
$_SESSION['registered'] = true;
and checking it on the first page
if (isset($_SESSION['registered'])) {
unset($_SESSION['registered']);
// shot the message
}
Typically you would set your flag for success in the session to display this message when the next page loads. This is commonly referred to as a Flash Message. You would then check the value/existence of this session flag and show your message or not accordingly. In most frameworks there is built in functionality for this which includes the clean up of the flag on the next request so that the message is only displayed directly after the action generating it is taken.
From the CI Sessions Documentation:
CodeIgniter supports "flashdata", or session data that will only be
available for the next server request, and are then automatically
cleared. These can be very useful, and are typically used for
informational or status messages (for example: "record 2 deleted").
Note: Flash variables are prefaced with "flash_" so avoid this prefix
in your own session names.
To add flashdata:
$this->session->set_flashdata('item', 'value');
You can also pass an array to set_flashdata(), in the same manner as
set_userdata().
To read a flashdata variable:
$this->session->flashdata('item');
If you find that you need to preserve a flashdata variable through an
additional request, you can do so using the keep_flashdata() function.
$this->session->keep_flashdata('item');
You should have some verification checks in your code that handles the processing of the form data to make sure that the required fields are filled out. Otherwise, you should be redirecting to your first page to have the user fill out the form.
Also, this could be handled via AJAX, but that would be a second step to having the proper verification in your form-processing page
HTML:
<form method="post">
<input type="text">
<input name="submitted" type="submit">
</form>
PHP:
if($_POST['submitted']{
//post was submitted process it
if(/*whatever you're doing to the form succeeds*/){
//show success
}
}
POST will not show variables in the URL.
Several solutions here, one would be to check for the form submission and if it hasn't been submitted redirect to the page with the form on it.
ie:
<?php
if (isset($_POST['submit']))
{
// process the form
}
else
{
//redirect to the form itself
header( 'Location: http://www.yourform.com' ) ;
}
?>

Prevent form resubmit in Zend framework?

An action within a controller generates the next id from the database and displays it on screen as reference. How can I prevent the action being called again if the user clicks refresh.
The post-redirect-get pattern with Zend Framework would generally involve leaving the action of the form empty (so it posts to itself) and then redirecting when you don't want to display the form again (so upon success).
public function newAction() {
$form = new Form_Foo();
if($this->_request->isPost()) {
if($form->isValid($this->_request->getPost()) {
//save or whatever
return $this->_redirect('path/to/success');
}
// else fall through
}
$this->view->form = $form;
}
if ($this->isPost()) {
// Check validation
if ($error) {
$dataToMove = array();
// $dataToMove is array that you want to pass with redirect
// It can be an array of errors or form data that user has entered
// Use FlashMessenger helper to pass data to redirection via Zend_Session
$this->_helper->getHelper('FlashMessenger')->addMessage($dataToMove);
// And redirect page to form url
$this->_helper->getHelper('Redirector')->goToUrl('/form/url/');
}
// If not posted, get data from FlashMessenger
$data = $this->_helper->getHelper('FlashMessenger')->getMessages();
// And assign to view or make that you want
$this->view->formData = $data;
Although this is older post people still come here for answers, so let me help a bit more.
Redirecting form is great and useful but we are still not preventing peple from clicking back button and resubmitting that way.
The solution is to either show the form as popup and make it disapear when done (easily done with jquery) or generate unique id for each transaction and checking if id was previously used.
See article: http://www.boutell.com/newfaq/creating/stoprefresh.html
Hope it helps.
You can do this by implementing a 302 redirect
header('HTTP/1.1 302 Found');
header('Location: displayId.php?id=5');
die();
Assuming you have these pages
form.php
processForm.php
displayId.php
Form.php only displays form and sends data via POST to processForm.php.
Within processForm.php you can parse data and issue the redirect to displayId.php with id you want to display in GET parameter.
This way when user refreshes the page (displayId.php) the form data is not processed again.
I know you're trying to do this in Zend Framework but I'm just saying I'm after the same functionality. Just moved everything to ZF and I'm quite disappointed to see that this functionality isn't built in.
I used to have every form submit to process.php which processed all GET, POST requests and then saved the results (like error and success messages) and redirected you to the new place.
If $_SESSION['post_data'] was set, I would $_POST = $_SESSION['post_data']; and then remove it from the session.
This worked great but now I'm gonna need the same in ZF :D As I say... a little disappointed as I don't believe ANYONE wants a dialog to appear asking about resubmitting data.. what the hell does that mean to your enduser? nothing!

Categories