I have a page "bottom1.php" it has 16 select menus, labled rating1-rating16.
When the user submits this form, the next page has a script that looks like this:
//pulling data from post into array.
import_request_variables("p", "form_");
$scores= array($form_rating1,$form_rating2,$form_rating3,$form_rating4,$form_rating5,$form_rating6,$form_rating7,$form_rating8,$form_rating9,$form_rating10,$form_rating11,$form_rating12,$form_rating13,$form_rating14,$form_rating15,$form_rating16);
//putting array into session
$_SESSION['scores']=$scores;
the user is then directed to another page where an additional 16 selections are made, then the same script is ran, only this time the array is stored into the session as "scores2".
The user is shown the output from each array, and then when the user confirms that the values are correct, each member of the scores, and scores2 array is parsed out, put into another variable, and then inserted into a database.
I know this is a primitive way of accomplishing this, but its the only way I know how.
This method worked with php configuration of 5.2.13, but I switched to a server with a configuration of 5.1.6 and now this script wont work. This script is critical to my site. Thanks for your help!
The parsing script looks like this:
$fpage=$_SESSION['scores'];
$spage=$_SESSION['scores2'];
$score1 = $fpage['0'];
$score2 = $fpage['1'];
$score3 = $fpage['2'];
$score4 = $fpage['3'];
$score5 = $fpage['4'];
...
$score31 =$spage['13'];
$score32 =$spage['14'];
$score33 =$spage['15'];
And then I insert $score1 - $score33 into my db..
The way you are doing it isn't exactly safe, for the same reason register_globals() is/was a bad idea. If you happen to prefix one of your internal variables with 'form_', the user could overwrite that value and potentially inject harmful code (depending on how that variable is used).
A better way to do this would be to filter the array directly into a new array using array_filter() or preg_grep().
Oliver A.'s solution only works in the scenario that all of the array keys will be in the form of 'form_rating', but your original script assumed a prefix of 'form_'.
preg_grep could be used as follows:
$keys = preg_grep('/^form_/', array_keys($_POST));
$scores = array();
foreach ($keys as $key) {
$scores[$key] = $_POST[$key];
}
I do not have a php enviroment to test this right now but this should work:
$scores = array();
for($i=1;array_key_exists("form_rating{$i}",$_POST);$i++){
$scores[] = $_POST["form_rating{$i}"];
}
EDIT: I tested and working
If the script does not work when PHP changes version then:
Check the logs to see the errors
Check the PHP Changelog for any function or control structure change that my halt your script.
Just an issue that it happen to me a lot when switching between 5.1 and 5.2 is the Elvis operator ?: which is not recognized in php 5.1.
This is why is important to develop on the same kind of configuration that the server has, or to implement unit-testing and automatic deployments which can detect this problems before reaching production.
Related
Hello CodeIgniter users.
I have a problem with flash data and I would like some help. My CI version is 2.1.4.
I am using CI flash data to store data temporarily for a form that consists of multiple pages. Data entered on each page is stored so it can be accessed on the next pages and finally all data is entered int the database.
Now to keep data stored through multiple pages, instead of only one, I extended the Session class with the following function:
function keep_all_flashdata($prefix = '')
{
$userdata = $this->all_userdata();
foreach ($userdata as $key => $value)
{
if (strpos($key, ':old:' . $prefix))
{
$new_flashdata_key = str_replace(':old:', ':new:', $key);
$this->set_userdata($new_flashdata_key, $value);
}
}
}
This function preserves all flash data (or optionally only flash data that starts with a certain string) for another redirect. It is similar to the keep_flashdata function except for the fact that it works for multiple items without requiring their exact name.
After calling this function, both :old: and :new: keys are stored in the session data. Then after a redirect, old keys are removed and new keys are set to old. Then, if there's another page, I call keep_all_flashdata() again and so on until the last page.
This works fine when I'm working on my local WAMP server, but on my actual server, all flashdata just gets removed after a redirect, even if it has :new: in the key. I confirmed my keep_all_flashdata() function works by checking the contents of session->all_userdata() and everything looks as expected.
I am using some AJAX calls, but they should not erase flash data (a known issue) as I've prevented this with $this->CI->input->is_ajax_request() before flashdata is cleared (in the sess_update() and _flashdata_sweep() functions).
Is this a bug in CodeIgniter or am I doing something wrong? Any help is appreciated.
I think your if statement is causing the problem. I'm assuming that ":old:" or ":new:" is used as prefix for every key you store in a session?
strpos() returns the position of where the needle exists so that would be 0 when checking a key with the prefix ':old:'. That's intended as old flashdata needs to be removed. I tested the following piece of code:
$flashDataKey = ':new:myKey';
die(var_dump(strpos($flashDataKey, ':old:')));
Which returns false as expected since the needle was not found. Resulting in not storing the flashdata as ':old:' and keeping it for the next request.
I'm not sure why this is working on your localhost. You should change your if statement to:
if( strstr($key, ':new:') !== false)
Now only keys containing the string ':new:' will pass and everything else will return false. Hope this helped!
I have a website where the front page contains a search form with several fields.
When the user performs a search, I make an ajax call to a function in a controller.
Basically, when the user clicks on the submit button, I send an ajax call via post to:
Route::post('/search', 'SearchController#general');
Then, in the SearchController class, in the function general, I store the values received in a session variable which is an object:
Session::get("search")->language = Input::get("language");
Session::get("search")->category = Input::get("category");
//I'm using examples, not the real variables names
After updating the session variable, in fact, right after the code snippet shown above, I create (or override) a cookie storing the session values:
Cookie::queue("mysite_search", json_encode(Session::get("search")));
And after that operation, I perform the search query and send the results, etc.
All that work fine, but I'm not getting back the values in the cookie. Let me explain myself.
As soon as the front page of my website is opened, I perform an action like this:
if (!Session::has("search")) {
//check for a cookie
$search = Cookie::get('mysite_search');
if($search) Session::put("search", json_decode($search));
else {
$search = new stdClass();
$search->language = "any";
$search->category = "any";
Session::put("search", $search);
}
}
That seems to be always failing if($search) is always returning false, and as a result, my session variable search has always its properties language and category populated with the value any. (Again: I'm using examples, not the real variables names).
So, I would like to know what is happening here and how I could achieve what I'm intending to do.
I tried to put Session::put("search", json_decode($search)); right after $search = Cookie::get('mysite_search'); removing all the if else block, and that throws an error (the ajax call returns an error) so the whole thing is failling at some point, when storing the object in the cookie or when retieving it.
Or could also be something else. I don't know. That's why I'm here. Thanks for reading such a long question.
Ok. This is what was going on.
The problem was this:
Cookie::queue("mysite_search", json_encode(Session::get("search")));
Before having it that way I had this:
Cookie::forever("mysite_search", json_encode(Session::get("search")));
But for some reason, that approach with forever wasn't creating any cookie, so I swichted to queue (this is Laravel 4.2). But queue needs a third parameter with the expiration time. So, what was really going on is that the cookie was being deleted after closing the browser (I also have the session.php in app/config folder set to 'lifetime' => 0 and 'expire_on_close' => true which is exactly what I want).
In simple words, I set the expiration time to forever (5 years) this way:
Cookie::queue("mysite_search", json_encode(Session::get("search")), 2592000);
And now it seems to be working fine after testing it.
Alright, sooooo... The issue is this: I am LPUSH'ing a variable value to a list called "keys". When I try to get and output the value of that list... it claims the list is empty (bool(false)). The syntax seems correct. This code has worked on other occasions (in fact, I am merely going through each function and testing/refactoring/improving what I have already written). I got snagged on this, and I'm completely boggled. Here's the code (with relevant notes):
$kw = $_REQUEST['keyword']; //we're passing a value to this in a query string
if(empty($kw)){
$key = 'default';
createRedis($key);
}else{
$key = $kw;
createRedis($key);
}
function{
$key = $a;
$r = new Redis();
$r->connect( 'localhost' );
$r->LPUSH( 'keys',$key ); // $key echos a value when one is passed in
echo $key; // a query string, BUT....
$keys=$r->get('keys'); //'keys'... the redis list
var_dump($keys); // throws a bool(false) when dumped
}
Is there something crazy that I'm missing? Redis is tested on my server as working. I, otherwise, am unable to sort out what the heck is wrong with this. Here's the documentation on LPUSH for phpredis (which is what we are using (it is also installed and working)): https://github.com/nicolasff/phpredis#lpush
and
the documentation for this on the Redis website (these are CLI examples):
http://redis.io/commands/lpush
Any help is sincerely appreciated. Perhaps I am using an ineffective method to test whether or not the redis list 'keys' is retaining value? (That was the whole purpose of the dump).
You have to use lrange instead of get:
$keys = $r->lrange('keys', 0, -1);
Sorry if I'm duplicating threads here, but I wasn't able to find an answer to this anywhere else on StackOverflow.
Basically what I'm trying to do is make a list in which variables entered in a form by a user can be kept. At the moment, I have the code which makes this possible, and functional, however the variables entered in the form only appear on the list after the user hits submit... As soon as I refresh the page or go to the page from somewhere else, the variables disappear. Is there any way I can stop this from happening?
Edit: here are the codes:
//Page 1
<?php
session_start();
$entries = array(
0 => $_POST['signup_username'],
1 => $_POST['signup_email'],
2 => $_POST['signup_city']);
$entries_unique = array_unique($entries);
$entries_unique_values = array_values($entries_unique);
echo "<a href='Page 2'>Link</a>";
$_SESSION['entries_unique_values'] = $entries_unique_values;
?>
//Page2
<?php
session_start();
$entries_unique_values = $_SESSION['entries_unique_values'];
foreach($entries_unique_values as $key => $value) {
$ValueReplace = $value;
echo "<br /><a href='http://example.com/members/?s=$ValueReplace'>" . $value . "</a><br/>";
}
?>
Your question is really quite vague. the answer depends on how much data you have to store, and fopr how long you need it to exsist.
By variable I assume you mean data the user has entered and that you want to put into a variable.
I also presume that the list of variables is created by php when the form is submitted.
Php will only create the variable list when the form is submitted as php is done entirely on the server, therefore you will not have or see the variables until the form is submitted.
if you wanted to be able to see the list as it is being created you could use javascript then once you have you php variables the javascript list isn't necesary.
each time you request a php page wheather it is the same one or not the server generates a totally new page, meaning all unhardcoded variables from previous pages will be lost unless you continually post the variables around the pages the server will have no memory of them.
You have a few viable options.
) keep passing the user created variables in POST or GET requests so each page has the necesary info to work with. Depending on the situation it might or might not be a good idea. If the data only needs to exsits for one or two pages then it is ok, but bad if you need the data to be accessable from any page on your web.
2.) start a session and store the variables in a session. Good if the data only needs to be around while the user is connected to the site. but will be lost if user close window or after a time.
3.) place a cookie. not a good idea but ok for simple data.
4.) create a mysql database and drop the variable info in there. great for permanent data. this is how i always complex user data.
just a few ideas for you to look into as it is difficult to see what you really mean. good luck.
use PHP session or store variable values in Cookies via JS or using PHP. It would be nice if you show your working codes :)
Your idea is fine, however you just need to add a little condition to your Page 1 that only set your SESSION values when POST is made, that way it will keep the values even if you refresh. Otherwise when you visit the page without a POST those values will be overwritten by blank values, which is what you are seeing now. You can modify it like
<?php
session_start();
if(isset($_POST["signup_username"]))
{
$entries = array(
0 => $_POST['signup_username'],
1 => $_POST['signup_email'],
2 => $_POST['signup_city']);
$entries_unique = array_unique($entries);
$entries_unique_values = array_values($entries_unique);
$_SESSION['entries_unique_values'] = $entries_unique_values;
}
echo "<a href='http://localhost/Calculator/form2.1.php'>Link</a>";
?>
You could use JavaScript and HTML5 local storage.
Here is what I would do in JavaScript. Is there any way to do it in php?
I am working on a project that needs this functionality but cannot use JavaScript.
setInterval ( "checkHistory()", 1000 );
function checkHistory() {
if (oldHistLength != history.length) {
removegateway();
oldHistLength = history.length;
}
}
Sorry to say that it's not possible to do that using PHP. Your only option is to use JavaScript somewhere.
You can however achieve what I believe you're trying to do with another technique - PHP Sessions and Request URIs.
This involves storing the user's accessed URLs into a variable (or you could use MySQL) which can be referenced anywhere on the website within that current session.
Here's an (untested) example:
<?php
session_start();
// Retrieve/create the current list
if( isset($_SESSION['history']) ) {
$history = $_SESSION['history'];
} else {
$history = new array();
}
// Add the current URL to the history array
array_push($history, $_SERVER['REQUEST_URI']);
// Do anything else you want to here
// Store the array again
$_SESSION['history'] = $history;
?>
In your code, you can keep an array containing the values of $_SERVER['php_self'], serialize() it, and store it in a session variable. This may not be sufficient for what you are trying to do though. I'm not sure what removegateway() does, but is this code attempting to prevent the back button from being used?
If you prevent the pages from being cached, you might be able to compare the second to the last value in your array to the current page, and if they match, you detected a back button. This would only be possible if there's no way to go back to the previous page on the front end.
Preventing the back button is generally considered a Bad Thing, so it might be better to reconsider the way you are doing things and come up with a better solution.