Looping through Checkboxes PHP - php

I want to insert whether or not a checkbox was selecting into MySQL, simply by adding 1 or 0 to the column that corresponds to the value. I am having a problem with the 0s, detailed below.
Here is an example of the checkboxes
<input type='checkbox' name='class[]' value='mathhl' id="mathhl">
For simplicity I added this
$classes = $_POST["class"];
Here is the foreach loop to check the values of the checkboxes.
foreach($classes as $value) {
if (!isset($value)) {
$value = 0;
}
else {
$value = 1;
}
echo $value;
}
For some reason, it only returns the 1s, but not 0s! I am new to PHP, so I'd like to know where exactly I'm going wrong with this, thanks!

Only checked checkboxes are sent to the server. So, if the value is not present in the array, that's because the box wasn't checked.
You can simplify your logic by making the values the keys in your array:
<input type='checkbox' name='class[mathhl]' value='1' id="mathhl">
Now, you don't have to loop over $_POST['class']. Instead, you can take an array of the all the keys (which you should already know):
$keys = array( 'mathh1', 'mathh2', 'mathh3');
And form an array with the default values (say 0):
$defaults = array_combine( $keys, array_fill( 0, count( $keys), 0));
And merge the $_POST array with the defaults array:
$results = array_merge( $defaults, $_POST['class']);
Now, $results will contain an associative array, with the keys being the columns and the values being 1 or 0, depending on whether or not the checkbox was checked. Be careful, as somebody can post and data they want to $_POST, so it may not be only 1's and 0's.

Related

How to delete last value in foreach loop

I have a dynamic multi input. When submit form, inserting array values. But I want to insert without 'submit' value.
This is the foreach loop, (sql secure not included)
if (isset($_POST['submit'])) {
$nearest = $db->prepare('insert into nearest set place=?, distance=?');
$i = 0;
foreach ($_POST as $val) {
$place = $_POST['place'][$i];
$distance = $_POST['distance'][$i];
$nearest->execute([$place, $distance]);
$i++;
}
}
This loop inserted '$_POST' values and inserted empty row.
If you want to keep the loop you can use array_slice to not include the last item in the loop.
Array_slice will take items from 0 (not literal, but the first item) to second to last (-1).
http://php.net/manual/en/function.array-slice.php
EDIT; I think you need a for loop to loop the count of "place".
if (isset($_POST['submit'])) {
$nearest= $db -> prepare('insert into nearest set place=?, distance=?');
for($i=0; $i< count($_POST['place']; $i++){
$place = $_POST['place'][$i];
$distance= $_POST['distance'][$i];
$nearest-> execute([$place , $distance]);
$i++;
}
}
example: https://3v4l.org/F47ui
You can simply remove your submit key from $_POST prior doing your loop with just regular unset(). But this is bad approach. What I'd rather recommend doing instead is to "isolate" your data, and instead of this:
<input name="distance" ... >
make all your imputs like this:
<input name="data[distance]" ... >
then you just need to loop over "data" (name as you like) array:
foreach($_POST['data'] as val)
Also, resist from removing last element in blind, because it's based on false assumption that this is always your "submit" element. What if you add more submit buttons to the form? or the order will change?

How to update one element of an array according to a condition on another element?

I have an array of associative arrays whose names (this is one of the keys of the assoc array) are given below:
{'Red', 'Blue', 'Green'}
Now I have another larger array with names as one of the keys. Like
{'id'=>'23fe54','names'=>'Red','value'=>'3'},{'id'=>'90ks21','names'=>'Red','value'=>'4'},{'id'=>'44cb12','names'=>'Blue','value'=>'1'};
According to this I want to update the smaller (the first one) array.
The names key of the larger array tells us which assoc array of the smaller array needs to be updated. I want to then add the value to one of the fields of the smaller array.
The question is how do I select the shorter array using the condition: whether these two fields match. How do I make sure only that one gets updated?
EDIT: Expected output:
{'names'=>'Red', 'value'=>'7'},{'names'=>'Blue','value'=>'1'};
I would do this :
<?php
$names = array('Red', 'Blue', 'Green');
$values = array(
array('id'=>'23fe54','names'=>'Red','value'=>'3'),
array('id'=>'90ks21','names'=>'Red','value'=>'4'),
array('id'=>'44cb12','names'=>'Blue','value'=>'1')
);
// prepare the result array
$results = array();
foreach($names as $name) {
$results[$name] = array('names' => $name, 'value' => 0);
}
// compute values
foreach($values as $value) {
$results[$value['names']]['value'] += $value['value'];
}
// keep only values
$results = array_values($results);
// print "jsonified" result
echo(json_encode($results));
?>

Replace single value in multidimensional array

I am trying to unset/remove then replace/update a single value from a post meta field, but my code for array_push() and unset() are removing all of the values from each array.
Here are the two halves of the code I am currently using.
First, to find and remove the old value:
$ID = $_GET["post_id"];
$old = $entry["85"];
$old_meta = array();
$old_meta = get_post_meta($old,'_website',false);
if(in_array($ID, $old_meta[current][items])){
unset($old_meta[current][items][$ID]);
}
update_post_meta($old,'_website',$old_meta);
Second to append the new value to the appropriate location:
$port = $entry["24"];
$new_meta = array();
$new_meta = get_post_meta($port,'_website',false);
$new_meta[content][items] = array();
array_push($new_meta[content][items],$ID);
update_post_meta($port,'_website',$new_meta);
It works to unset and insert the correct value, but any other values that were there (for both updating or unsetting) in the meta[current][items] array are removed.
Before running any functions the array looks like this:
pastie.org/8112933
After I run array_push it looks like this:
pastie.org/8112956
After unset it looks like this:
pastie.org/8112974
in_array checks to see if an element in array has a value equal to that value, not a key. So you would need to do something like this:
if(in_array($ID, $old_meta['current']['items'])){
foreach($old_meta['current']['items'] as $key => $val) {
if($val == $ID) {
unset($old_meta['current']['items'][$key]);
}
}
}
If you need to check for a key not a value just replace in_array() with array_key_exists() and keep your current code.

How to avoid one or more elements in option array of select box in cake php

In cake php how to avoid one or more elements in option array of select box.
$options = array('One','Two','First','Second');
echo $this->Form->select('trial', $options);
Here I want to avoid 'First' and 'Second' from array, here option array is coming from DB.
$options = array('One','Two');
Is it possible to do it by any alteration in select method of cake php(i.e array $attributes or anything else ) or manually search the array and drop the values ?
Use array_slice():
echo $this->Form->select('trial', array_slice($options, 0, 2));
Edit:
An alternative solution, if you don't know the order of the array, and if the values are unique, is by using array_search():
unset($options[array_search('First', $options)]);
Or if the values aren't unique and you'd like to remove them all, then array_keys() could be useful:
$keys = array_keys($options, 'First');
foreach ($keys as $key)
{
unset($options[$key]);
}

ow to handle possible duplicate array keys

I am trying to figure out how I can handle possible duplicate array keys.
I have this form with a select dropdown which can select multiple options (more than 1). And I am using jQuery.serialize() to serialize the form on submit.
The serialized string for a multi-select element would look like so:
select=1&select=2&select=3 // assumming I selected first 3 options.
Now in the PHP side, I have the following code to handle the "saving" part into a database.
$form_data = $_POST['form_items'];
$form_data = str_replace('&','####',$form_data);
$form_data = urldecode($form_data);
$arr = array();
foreach (explode('####', $form_data) as $part) {
list($key, $value) = explode('=', $part, 2);
$arr[$key] = $value;
}
Ok this all works for the rest of the form elements but when it comes to the select element, it only picks the last selected key/value pair. So my array now looks like this:
Array ( [select_element] => 3)
What I need, is for it to look like:
Array ( [select_element] => '1,2,3')
So I guess what I am asking is based on my code, how can I check if a key already exists and if it does, append to the $value.
If you can modify the client-side code, I would rather change the name of the select to select[], that way it will be parsed as an array in your server script.
You can't have multiple keys with the same name... They're unique keys. What it's doing is setting select = 1, then select = 2, then select = 3 and you end up with your final value of 3.
If you want to allow multiple choices in your select menu, you should change the name of the element so that it submits that data as an array, rather than multiple strings:
<select name="select[]" multiple="multiple">
which should result in something like this instead:
select[]=1&select[]=2&select[]=3
and when PHP requests that data, it will already be an array:
$data = $_POST['select'];
echo print_r($data); // Array(1, 2, 3)
PHP has its own way of encoding arrays into application/x-www-form-urlencoded strings.
PHP's deserialization of x-www-form-urlencoded is implemented by parse_str(). You can think of PHP as running these lines at the beginning of every request to populate $_GET and $_POST:
parse_str($_SERVER['QUERY_STRING'], $_GET);
parse_str(file_get_contents('php://input'), $_POST);
parse_str() creates arrays from the query string using a square-bracket syntax similar to its array syntax:
select[]=1&select[]=2&select[]=3&select[key]=value
This will be deserialized to:
array('1', '2', '3', 'key'=>'value');
Absent those square brackets, PHP will use the last value for a given key. See this question in the PHP and HTML FAQ.
If you can't control the POSTed interface (e.g., you're not able to add square-brackets to the form), you can parse the POST input yourself from php://input and either rewrite or ignore the $_POST variable.
(Note, however, that there is no workaround for multipart/form-data input, because php://input is not available in those cases. The select=1 and select=2 will be completely and irretrievably lost.)
Ok, I was able to resolve this issue by using the following code:
if (array_key_exists($key, $arr)) {
$arr[$key] = $arr[$key].','.$value;
} else {
$arr[$key] = $value;
}
So now the loop looks like this:
foreach (explode('####', $form_data) as $part) {
list($key, $value) = explode('=', $part, 2);
if (array_key_exists($key, $arr)) {
$arr[$key] = $arr[$key].','.$value;
} else {
$arr[$key] = $value;
}
}
This will essentially string up the value together separated by a comma which can then be exploded out into an array later.
You should change your client-side code to send the augmented value: array.join(","); and use that in your PHP side. Because when your data reaches your script, the other values have already been lost.
This should give you the solution you require
$form_data = str_replace('&','####',$form_data);
$form_data = urldecode($form_data);
$arr = array();
foreach (explode('####', $form_data) as $part) {
list($key, $value) = explode('=', $part, 2);
if (isset($arr[ $key ])) {
$arr[$key] = ','.$value;
} else {
$arr[$key] = $value;
}
}

Categories