PHP => $_SESSION Array only keeps last variable - php

I'm building an interface for an online shop, where every item is a FORM and the BUY button is a submit,it submits the name and price of the clicked form and that data is displayed on a CONFIRM ORDER page. On that confirm order page I've created an array as follows
if (!isset($input_order_arr)) {
$input_order_arr = array();
}
After that I fetch the posted variables and push them into the array
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (!empty($_POST['item-title']) && !empty($_POST['item-price'])) {
$item_title = test_input($_POST['item-title']);
$item_price = test_input($_POST['item-price']);
array_push($input_order_arr,$item_title,$item_price);
}
}
$_SESSION['chosen_item'] = $input_order_arr;
*NOTE : test_input is a function that does striplashes , htmlspecialchars and htmltrim, for security purposes. (someone might edit the value of the item via the Chrome developer console? not sure if that holds any threat though)
And after that the value is displayed in a table like so
<?php if (isset($_SESSION['chosen_item'])) {
foreach ($_SESSION['chosen_item'] as $value) {
echo "<td>" . $value . "</td>";
}
} ?>
And here comes the problem.
If you order an item its price and name are displayed, but if u go back and you order another item, the previous item and its price are lost, as if its not adding new lines to the array,but replacing the old ones, or the session only saves data from one action, which wouldn't make any sense, since thats what $_SESSION is about, the code is presented with session_start(); in every page that is using the $_SESSION variable.
Main Question - Why could it be that the $_SESSION Array is losing its older inputs?

You could push directly into the session like this
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (!empty($_POST['item-title']) && !empty($_POST['item-price'])) {
array_push($_SESSION['chosen_item'],
test_input($_POST['item-title']),
test_input($_POST['item-price'])
);
}
}
//$_SESSION['chosen_item'] = $input_order_arr;
Or as your test_input() is likely doing nothing useful
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (!empty($_POST['item-title']) && !empty($_POST['item-price'])) {
array_push($_SESSION['chosen_item'],
$_POST['item-title'],
$_POST['item-price']
);
}
}
You might find this data easier to use later by doing
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (!empty($_POST['item-title']) && !empty($_POST['item-price'])) {
array_push($_SESSION['chosen_item'],
array('title' => $_POST['item-title'],
'price' => $_POST['item-price']
)
);
}
}

you need $_SESSION['chosen_item'][]=$input_order_arr; your overwriting the same index instead of creating new one
$_SESSION['chosen_item'][]=$input_order_arr;
Note : And also it should be moved inside the if statement .to avoid empty array storing in session

When you go back, you basically are setting the chosen_item array element to empty, since $input_order_arr would not contain anything when you haven't submitted a form.
You should append to the session array only if there is a nonempty $input_order_arr array:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (!empty($_POST['item-title']) && !empty($_POST['item-price'])) {
$item_title = test_input($_POST['item-title']);
$item_price = test_input($_POST['item-price']);
array_push($input_order_arr,$item_title,$item_price);
$_SESSION['chosen_item'][] = $input_order_arr;
}
}

Related

$_SESSION variable getting lost somewhere........or PHP ignoring "IF...ELSEIF"

I am having a problem with getting my PHP script to correctly read and execute my "IF.....ELSEIF" conditions.
In my first file, I have the following code :
if(isset($_POST['submit']) {
$selected_radio = $_POST['selection'];
$_SESSION['my_selection'] = $_POST['selection'];
if (($selected_radio == '25') {
header("url=http://xxxxxxxxxxxxxxxxx");
}
elseif (($selected_radio == '50') {
header("url=http://xxxxxxxxxxxxxxxxx");
}
}
That was the easy part.
If either "radio button" is selected, I have a Javascript function which opens a "new (child) window"
That's also easy.
But, then, comes the hard part : within that new window, the user has to select from another choice of radio buttons :
if(isset($_POST['submit']) {
$selected_radio = $_POST['my_response'];
if (($_POST['my_response'] = 'yes') && ($_SESSION['my_selection'] = '25'))
{
echo '<script type="text/javascript">window.opener.location =
"/PHP/25.php";setTimeout("window.close();", 1000);</script>';
}
elseif (($_POST['my_response'] = 'yes') && ($_SESSION['my_selection'] =
'50')) {
echo '<script type="text/javascript">window.opener.location =
"/PHP/50.php";setTimeout("window.close();", 1000);</script>';
}
Basically, this means : if the user selects "yes" in the current (child) window, then the window closes, and the parent window re-directs to "25.php" or "50.php"..........depending on the value of the $_SESSION['my_selection'] --- which was selected earlier in the parent-window
But, for some reason, it's not working. My code is executing only the FIRST IF-condition :
if (($_POST['my_response'] = 'yes') && ($_SESSION['my_selection'] = '25'))
{
echo '<script type="text/javascript">window.opener.location =
"/PHP/25.php";setTimeout("window.close();", 1000);</script>';
}
It is completely ignoring the second one.............even if the user had earlier selected "50" in the parent-window.
My first thought was : the SESSION value of the radio-button ---- $_SESSION['my_selection'] --- was not being carried-over into the new (child) window.
But, I used "echo" to verify that this was working properly. The value was indeed being carried-over into the new (child) window.
However, after the child-window closes, and the parent-window is re-directed, I used "echo" again to track any errors........and it showed that : the value of $_SESSION['my_selection'] is always equal to "25" !
In a nutshell : why is the second IF-statement being ignored??
elseif (($_POST['my_response'] = 'yes') && ($_SESSION['my_selection'] =
'50')) {
echo '<script type="text/javascript">window.opener.location =
"/PHP/50.php";setTimeout("window.close();", 1000);</script>';
($_POST['my_response'] = 'yes') && ($_SESSION['my_selection'] = '25')
^ ^
A single equals sign is an assignment and as the value you are assigning is truthy the if will always evaluate to true. Use == for a comparison.
You are using = instead of == in nearly all statements:
if (($_POST['my_response'] = 'yes')
should be
if (($_POST['my_response'] == 'yes')
This way, you don't check if $_POST['my_response'] is equal to "yes", but if it is possible to assign "yes" to $_POST['my_response']. As a result, all your if statements are true.

Do the same - just with less code

I've been trying to work my way to it simply must check it with all inputs in the present that I might have 100 lines so got it done less to just check it all together for an error or what?
What I think about that: instead of taking 14 lines of code that make it less but may be the same,
if($_POST["email"] == "")
{
$error = 1;
}
if($_POST["pass1"] == "")
{
$error = 1;
}
if($_POST["pass2"] == "")
{
$error = 1;
}
if($_POST["fornavn"] == "")
{
$error = 1;
}
if($_POST["efternavn"] == "")
{
$error = 1;
}
if($_FILES["file"] == "")
{
$error = 1;
}
Just create an array of field names and loop over them...
foreach(array('email','pass1','pass2',...) as $field) {
if(empty($_POST[$field])) {
$error = 1;
}
}
$_FILES you will have to handle separately. You can create another loop if you want. The structure of $_FILES is different though; I think you should be checking the "error" field. Check the docs.
Another way to approach this, considering the fact that you don't seem to be performing different tests for each field, or responding with specific error messages, is to use array_diff_key:
$names = array('email', 'pass1', 'pass2', 'fornavn', 'efternavn', 'file');
$names = array_keys($names); // convert $names to keys
$posts = array_filter($_POST); // filter out any falsy values
$fails = array_diff_key($names, $posts); // check for the differences
$error = $fail ? 1 : 0;
If you then wish to respond with specific messages depending on what is missing, you already have a list of the problem parameters in $fails. If you wish to extend the above to take into account specific value checks, you could write your own array filter callback function and pass it's name as the second parameter to array_filter... however this wont allow you to choose a different filter response based on array key, only on array value. All because rather annoyingly array_filter doesn't receive a key value when filtering an array.

Keeping array from POST when using pagination link

I am having a litte issue with my searchengine.
It outputs the searchresult just fine, but when I am clicking a pagination link it fails, of course because it no longer have the $_POST array. I am using this piece of code:
if(empty($_POST) == false) {
$res = $search->search_ads($_POST);
if($res == false) {
$view->setData('numres', 0);
} else {
$view->setData('numres',$res[2]);
$view->setData('adverts', $res[0]);
}
$app->view()->setData('paginate', $res[1]);
$app->render('search.tpl');
} else {
$app->render('404.tpl');
}
When I click on f.x. "Page 2" it will render the 404 template.
Is there a way I can keep the $_POST array and reuse it in the search_ads function?
"paginate" contains the HTML for the pagination
<li><a class=\"paginate\" href=\"$target?page=$next_page&ipp=$this->items_per_page\">«</a></li>":"<li><span class=\"inactive\" href=\"#\">«</span></li>
use sessions.
session_start(); //on the top of your php file.
...
if(!empty($_POST))
$_SESSION['post_data']= $_POST;
...
if(empty($_SESSION['post_data']) == false) {
$res = $search->search_ads($_SESSION['post_data']);
...
}
Store the post array in a variable and use that elsewhere?
$post_array = $_POST;
$res = $search->search_ads($post_array);
You want to check for $_GET rather than $_POST on subsequent pages, as that's the method your using to pass the data:
href=\"$target?page=$next_page&ipp=$this->items_per_page\"
Will provide you with a $_GET array containing key value pairs:
$_GET['page'] = value of $next_page
$_GET['ipp'] = value of $this->items_per_page

code checks one checkbox or the other, but not both

So basically, I have a function that is ran when a post is created on wordpress. I've modified this function by adding the following code.
$episodeID = $_POST['item_meta'][137];
$episodeVersion = $_POST['item_meta'][357];
if ($episodeVersion == "Subbed") {
$value = array("Subbed");
update_field('field_48', $value, $episodeID);
}
else if ($episodeVersion == "Dubbed") {
$value = array("Dubbed");
update_field('field_48', $value, $episodeID);
}
This code basically says, if the value of a field in that post is "Subbed" then update another checkbox field by checking the "Subbed" checkbox. If it's "Dubbed" then update the checkbox field by selecting the "Dubbed" checkbox.
This works perfectly fine, however there is no time when both of these checkboxes are checked. If I add a post with the Dubbed, it'll check dubbed, then if I add a post with Subbed, it'll uncheck dubbed and check subbed.
So basically, how can I make it so it doesn't actually uncheck whatever has already been checked. So what should I use to check to see if the checkbox is unchecked or checked? Some type of boolean true / false?
Okay, so I was able to manipulate some of the code and get it to work eventually.
All I had to do was check if the Subbed checkbox was already checked when executing the dubbed if statement, and vice versa.
Here is the updated code
$episodeID = $_POST['item_meta'][137];
$episodeVersion = $_POST['item_meta'][357];
if ($episodeVersion == "Subbed" && !(get_field('episode_sdversion') && in_array('Subbed', get_field('episode_sdversion', $episodeID))) ) {
if (get_field('episode_sdversion') && in_array( 'Dubbed', get_field('episode_sdversion'))) {
$value = array("Subbed", "Dubbed");
} else {
$value = array("Subbed");
}
update_field('field_48', $value, $episodeID);
}
if ($episodeVersion == "Dubbed" && !(get_field('episode_sdversion') && in_array('Dubbed', get_field('episode_sdversion', $episodeID))) ) {
if (get_field('episode_sdversion') && in_array( 'Subbed', get_field('episode_sdversion'))) {
$value = array("Subbed", "Dubbed");
} else {
$value = array("Dubbed");
}
update_field('field_48', $value, $episodeID);
}

Looping through $_POST variables

Sorry i could not find a proper title to this question.
I have generated the following using a for loop and I have concatenated the names of the submits buttons using the pattern below:
submit_edit_category_1
submit_edit_category_2
submit_edit_category_3
echo "<input type='submit' value = 'Edit' name='submit_edit_category_" .
$obj_categories_admin->categories[$i]['category_id'] . "'/>";
I want to loop through these values so that I can the button action whichis edit_category and the category id which is 1,2 or 3. I want to so something like:
if(isset($_POST) == 'edit_category'))
{
//code here
}
Someone suggested me to do it this way:
name="submit[which_action][which_category]"
a1 = $_POST['submit'];
$which_action = reset(array_keys($a1));
$which_category = reset(array_keys($a1[$which_action]));
This does not seem to work..Can anyone give me a different way to do it?
Thanks!
UPD: Please, use Mike's advice. It's much better to have more structured data in POST.
foreach($_POST as $key => $val) {
if(strpos($key, 'submit_edit_category_') === 0 ) {
print $key.' => '.$val.'\r\n';
print substr($key, 21 /* or 22... or 23... try yourself */ );
}
}
here what I'd do:
for the actual form, I'd use array keys to communicate action and relevant id info.
$cat_id = $obj_categories_admin->categories[$i]['category_id'];
echo "<input type='submit' value = 'Edit' name='submit[edit_category][" . $cat_id . "]'/>";
then when posted, I can do:
<?php
list($action, $action_params) = each($_POST['submit']);
list($cat_id, $button_label) = each($action_params);
print_r($_POST['submit']); // prints array('edit_category' => array('1' => 'Edit'))
echo($action); //prints "edit_category"
print_r($action_params); //prints array('1' => 'Edit')
echo($cat_id); //prints "1"
echo($button_label); //prints "Edit"
edit: for more info on each(), go here: http://us2.php.net/each . I've personally always felt that 's lack of differentation between the button label and the it's value to be frustrating. Using an array key to stuff info into the button has always been my favorite hack.
You can try this:
foreach ($_POST AS $key=>$value) {
if (strpos($key, 'submit_edit_category_') !== false) {
$catID = (int)str_replace('submit_edit_category_', '', $key);
echo 'Category ID: ' . $catID . '<br />';
}
}
I'd change the way you build the name to this:
submit__edit_category__1
Then, try this:
function filter_by_submit($var)
{
return stripos($var, "submit") !== false ? true : false;
}
$submits = array_filter(array_keys($_POST), "filter_by_submit");
foreach ($submits as $sub)
{
if ($_POST[$sub] == "Edit")
{
list($submit, $action, $id) = explode("__", $sub);
break;
}
}
$submit will hold the string "submit". $action will hold "edit_category" and $id will hold the id of the pressed button. The pressed button is determined by matching its value to the tag's value (i.e., when submit__edit_category__1 is pressed, the value "Edit" is POSTed).

Categories