Session persistence with Zend framework - php

I'm having problems with storing variables in a $_SESSION variable.
I'm using Zend framework and building a 3 step application form. Now, when the first step is done, I store the data in MySQL database, and store the returned insert id in a session variable. Then I forward the page to another controller (step 2). When I forward the request, everything works fine and I can read the id from the session variable. But when I submit the second form (which has the same controller of step 2 as an action) the session is lost. I try to var_dump it, and it returns NULL.
Here's the code:
public function organizationAction()
{
$this->view->vals="";
$form=$this->getOrganizationForm();
$this->aplid=$_SESSION['appid'];
var_dump($_SESSION);
$firsttime=$this->getRequest()->getParam('firsttime',0);
//if(null==$this->aplid) $this->_forward('index','index');
if ($this->getRequest()->isPost() && $firsttime==0) {
if (!$form->isValid($_POST)) {
// Failed validation; redisplay form
$this->view->form = $form;
return false;
}
var_dump($_SESSION);
$values = $form->getValues();
$db=new Util_Database();
if($db->insertOrganization($values,$this->aplid))
$this->_forward('final');
else echo "An error occured while attempting to submit data. Please try agian";
}
$this->view->form=$form;
}
What is the problem here? I tried storing the session_id in the form, and then setting it before session_start(), but it starts a whole new session. Please help!

I'm not sure if this is going to help, because I'm not sure if something else might be happening in step 2. But here goes.
You might be inadvertently overwriting your session data. Here is what I came up with that might help give some ideas.
public function organizationAction() {
$this->view->vals = "";
$form = $this->getOrganizationForm();
$db = new Util_Database();
//This will only submit the form if the is post and firsttime == 0
if ($this->getRequest()->isPost() && $this->getRequest()->getPost('firsttime') == 0) {
//if form is valid set session and save to db
if ($form->isValid($this->getRequest()->getPost())) {
//We only want to initialize the session this time, if we do it
//on the next pass we may overwrite the information.
//initialize session namespace
$session = new Zend_Session_Namespace('application');
//get values from form, validated and filtered
$values = $form->getValues();
//assign form value appid to session namespace
$session->appid = $form->getValue('appid');
//assign session variable appid to property aplid
$this->aplid = $session->appid;
if ($db->insertOrganization($values, $this->aplid))
$this->_forward('final');
else
echo "An error occured while attempting to submit data. Please try agian";
} else {
//if form is not vaild populate form for resubmission
//validation errors will display of form page
$form->populate($this->getRequest()->getPost());
}
}
//if not post display form
$this->view->form = $form;
}
P.S. If your gonna go ZF...Go ZF! :)

Related

form values lost if captcha error in codeigniter php

I have created a website in php, the website has a signup form and google captcha in it. If the captcha is correct the form will submit successfully. If the captcha is wrong the same page will reload:
$this->session->set_flashdata('message', 'Captcha Error.');
redirect(base_url('signup'), 'Location');
The problem is the page is reloading with empty values, the user entered inputs are gone, can anyone please tell me what am i missing in my code?
Thanks in advance.
You can save your form value in session, and autofill the form based on data in session.
//set formdata to session
$data_session = array(
'name' => $name,
'email' => $email
);
$this->session->set_userdata('form_data', $data_session);
And set the data when you load the register page, and set the value to your view.
//load session data if exist
$data['name'] = null;
$data['email'] = null;
if ($this->session->userdata('form_data') != null)
{
$data['name'] = $this->session->userdata('form_data')['name'];
$data['email'] = $this->session->userdata('form_data')['email'];
}
$this->load->view('register_view',$data);
Dont forget to remove the session if signup is successful.
$this->session->unset_userdata('form_data');
Alternatively you can also use HTTP method and POST / GET the data to the new page (dont use HTTP GET if you want to send the password).

Redirect and POST at the same time

I have a form and I don't do client-side validation other than required attribute. I'm doing the validation on the server side.
lyrics/add.php
<form action="../scripts/lyrics/submit_lyrics.php" id="lyricsForm" method="post" autocomplete="off" enctype="multipart/form-data">
Form data is processed in a seperate php file. Retrieving and validating the form data in the following way:
scripts/lyrics/submit_lyrics.php
$form_data = new FormData(["artist", "album", "song", "year", "track_no", "lyrics"], "sssiis");
$form_data->validate();
What the validate method does is
public function validate() {
$valid = $this->check_form_data($fields);
$fields = implode(",", $fields);
if (!$valid) {
header("location: ".BASE."lyrics/add?status=error&problem=input&specifics=$fields");
exit;
}
}
check the form data and redirect the page (scripts/lyrics/submit_lyrics.php) to the form page (lyrics/add.php) with the information on validation (if it failed). Then I output an error message indicating that there's something wrong with the input using GET method.
I'm curious if I can do this using POST. I would need to modify this line
header("location: ".BASE."lyrics/add?status=error&problem=input&specifics=$fields");
make it redirect the page to BASE."lyrics/add" and also send the validation information using POST to that page. So I'd still be able output the validation error, but using POST instead of GET.
Is this possible?
No, this is not possible because you are rewriting the request. The browser will always send a "GET" request in response to a redirect request, unless it receives a 307 request in which it will repeat the request using the same method and parameters. See this related question on Programmers.
The workaround is to redirect to a new page with an embedded form that you generate, and have javascript POST that form for the user. It's an extra request but it's the only way to have the client make a second POST.
Using u_mulder's suggesion (storing values in a session), I've solved the problem in the following way:
scripts/lyrics/submit_lyrics.php
public function validate() {
$valid = $this->check_form_data($fields); // check if input fields are valid
$fields = implode(";", $fields); // invalid input fields
if (!$valid) { // not all fields are valid, so we return
session_start(); // start session
if (!isset($_SESSION["problem"])) { // making sure session variable doesn't exist
$_SESSION["problem"] = "input"; // error type: input, file_upload, db_insert, etc.
$_SESSION["specifics"] = $fields; // artist, album, etc. (for input)
}
header("location: ".BASE."lyrics/add?status=error"); // redirect to form page
exit;
}
}
lyrics/add.php
if (isset($_GET["status"])) {
$status = $_GET["status"];
switch ($status) {
case "error":
session_start();
if (isset($_SESSION["problem"])) {
$problem = $_SESSION["problem"];
$specifics = explode(";", $_SESSION["specifics"]);
$error_message = "There was an error.";
switch ($problem) {
case "input":
$error_message = "Invalid input on the following fields:";
break;
// other cases ...
}
session_destroy();
output("Error!", $error_message, $specifics);
} else {
// if the user reloads the page, session data is lost
// but we're still in the error page "lyrics/add?status=error" and have no error to show
// we either show an appropriate message or redirect to "lyrics/add"
session_destroy();
// output("Error!", "You're in the form validation error page, but there aren't any errors. Did you reload the page?");
// header("location: ".BASE."lyrics/add");
// exit;
}
break;
case "success":
// form submitted successfully
break;
}
} else {
// show form
}

Sign up with multiple forms

I'm using Laravel and in my website I need to make a registration throw many steps. There is a first view where the user enter his information and a profile picture then a second view to choose the account type and a third view to pay the inscription fee with Paypal.
I want to get all the information in the final view by using Input::all(), I hope there is an easy way to do that
I solved this myself by creating a php class which stores all this data and then create an object of this class and store that in a session.
class data{
public $data1;
public $data2;
public $data3;
//must checks if the data is complete
function checkdata(){
if(condition){
return true;
}else{
return false;
}
}
}
//Store data in session or load existing data from session.
if(isset($_SESSION["data"]){
$data = $_SESSION["data"];
}else{
$data = new data();
$_SESSION["data"] = $data;
}
//do with the data whatever needs to be done. change the variables if needed etc.
$data->$data1 = $_POST["data1"];
//once all data is complete send and save it where it needs to be saved and unset the session
if($data->checkdata()){
saveorsenddata($data);
unset($_SESSION["data"]);
}//else do nothing

PHP Session gets destroyed after redirection?

I am facing a very strange problem , i am doing CasLogin in my application..
i have successfully implemented CAS, i.e all values are set in $_SESSION variable after all proper validations, and successful login, but when i redirect it from CasLogin() action to Index Action $_SESSION contains nothing..
i am using Yii Frame Work.
here is code.
public function actionCasLogin($CID=NULL)
{
//code to be imported from GMS here
PhpCasControl::setPhpCasContext($CID);
phpCAS::setPostAuthenticateCallback(array($this,'_saveServiceTkt'));
$loginForm = new CasLoginForm;
// validate user input and redirect to the previous page if valid
if ($loginForm->login($CID)) {
if (Yii::app()->user->isGuest){
echo '<br> <br> This shows up..';
var_dump($_SESSION);
}
else{
echo 'Hello at caslogin <br>never shows up';
var_dump(Yii::app()->user->id);
}
$this->redirect(array('index'));
}
else {
throw new Exception("You don't have sufficient permissions to access this service. Please contact Administrator !");
}
}
this function Works Properly and if i put a EXIT; here it will display $_SESSION with all the desired values..
but after redirection... to index..
whose code is this..
public function actionIndex()
{
echo"hello at index";
if (! Yii::app()->user->isGuest) {
//#CASE 1: User is already logged in
$this->redirect(array("site/upload"));
}
else{
//#CASE 2: User is not Logged in
echo '<br>shows up with empty session<br>';
var_dump($_SESSION);
var_dump(Yii::getVersion());
exit;
$this->redirect(array("site/login"));
}
}
here $_SESSION is empty..
any explanation why this might be happening..
i am aware of CAS creating its own session by service ticket name.. i have handled that thing.. by RenameSession function, which i call in CasLoginForm..
whose code is this..
public function rename_session($newSessionId) {
//Store current session variables so that can be used later
$old_session = $_SESSION;
//Destroy current session
session_destroy();
// set up a new session, of name based on the ticket
$session_id = preg_replace('/[^a-zA-Z0-9\-]/', '', $newSessionId);
//start session with session ID as 1) service ticket in case of CAS login, 2) random sTring in case of local login.
session_id($session_id);
session_start();
//echo "<br>new session <br>";
//Restore old session variables
$_SESSION = $old_session;
//var_dump($_SESSION);
}
OK, i think that you should use session_id to change the id.
public function rename_session($newSessionId) {
// set up a new session id, of name based on the ticket
session_id(preg_replace('/[^a-zA-Z0-9\-]/', '', $newSessionId));
}

PHP Dynamic signup page

I wanted to create a dynamic signup.php. The algorithm is as follow:
Algorithm
when signup.php is requested by client, the code will attempt to check whether user send any data in $_POST.
if $_POST does not contains any data (means it's the first time user request for signup.php), a signup form will be return to the user, allowing user to enter all his/her details and again send back to signup.php through submit button.
if $_POST does contains data (means user has fill up the signup form and is now sending all the data back to signup.php), then the php code will attempt validate all those data and return result showing user has been successfully registered or error if failed to do so.
The problem I'm having right now is how am I going to check whether it's the first time user request for signup.php or not?
Use isset() to check if $_POST contains data.
http://php.net/isset
To answer your question, "how am I going to check whether it's the first time user request for signup.php or not?", honestly, probably for other users......
There are a few ways, cookies, storing request ips in a database, bleh, bleh, bleh. But...... None of them are guaranteed. The user can disable cookies, use a dynamic ip, etc. You could issue a unique hash and place it as a login.php?q=encValueForUniquePageRequest
but...... The architecture you laid out won't be practical.
Sorry :(
To check that request is POST:
<?php
if($_SERVER['REQUEST_METHOD']=='POST'){
//process new user
}
?>
Example:
<?php
Class signup_controller extends controller{
private $data = array();
private $model = array();
function __construct(Core $core){
parent::__construct($core);
/* load models - assign to model */
$this->model['page'] = $this->core->model->load('page_model', $this->core);
$this->model['auth'] = $this->core->model->load('auth_model', $this->core);
/* check script is installed - redirect */
if(empty($this->core->settings->installed)){
exit(header('Location: '.SITE_URL.'/setup'));
}
}
function index(){
/* do signup - assign error */
if($_SERVER['REQUEST_METHOD'] == 'POST'){
if($this->model['auth']->create_user(1)===false){
$this->data['error'] = $this->model['auth']->auth->error;
}
}
/* not logged in */
if(empty($_SESSION['logged_in'])){
/* assign form keys */
$_SESSION['csrf'] = sha1(uniqid().(microtime(true)+1));
$_SESSION['userParam'] = sha1(uniqid().(microtime(true)+2));
$_SESSION['passParam'] = sha1(uniqid().(microtime(true)+3));
$_SESSION['emailParam'] = sha1(uniqid().(microtime(true)+4));
/* get partial views - assign to data */
$this->data['content_main'] = $this->core->template->loadPartial('partials/signup', null, $this->data);
$this->data['content_side'] = $this->core->template->loadPartial('about/content_side', null, $this->data);
/* layout view - assign to template */
$this->core->template->loadView('layouts/2col', 'content', $this->data);
}
/* signed in - redirect */
else{
exit(header('Location: ./user'));
}
}
}
?>

Categories