I've got a dynamic form that allows a user to create as many form elements as they need -- then submit them. For this, I have prepared the input names as arrays like
<input name="title[]" ...
and posting them gives me output like
Array
(
[day] => 0
[project_id] => 5
[submit] => publish
[id] => Array
(
[0] => 4
[1] => 5
)
[title] => Array
(
[0] => Step 1
[1] => Step 2
)
[max_vol] => Array
(
[0] => 2
[1] => 3
)
[description] => Array
(
[0] => df dofi dofidfoi
[1] => dfvpdofvdpfo osd pod
)
)
I've created something that allows me to just grab the post arrays like so
foreach( $_POST as $post_key ) {
// ignore non-array post variables
if( is_array( $post_key ) ) {
foreach( $post_key as $form_value ) {
echo "$form_value\n";
}
}
}
/* ouputs...
4
5
Step 1
Step 2
2
3
df dofi dofidfoi
dfvpdofvdpfo osd pod
*/
which nicely sorts the non-arrays from the arrays, but I can't figure out how to take this variable number of created form elements and prepare them into an array variable that looks something like...
Array
(
[0] => Array
(
'id' => 4, 'title' => 'Step 1', 'max_vol' => '2', 'description' => 'df dofi dofidfoi'
),
[1] => Array
(
'id' => 5, 'title' => 'Step 2', 'max_vol' => '3', 'description' => 'dfvpdofvdpfo osd pod'
),
// could be more or less elements...
);
(I will be eventually passing these arrays to a MySQL query builder function).
Thanks.
How about creating a variable that is outside the scope of the foreach loop
$results = array();
foreach( $_POST as $post_key=>$post_value ) {
// ignore non-array post variables
if( is_array( $post_value ) ) {
foreach( $post_value as $form_key=>$form_value ) {
if (!isset($results[$form_key]))
{
$results[$form_key] = array();
}
$results[$form_key][$post_key] = $form_value;
}
}
}
// results is your array variable
print_r($results);
Iterate over some significant $_POST-array key, for example - id and get the values from other $_POST-arrays with the same index:
$values = array();
foreach ($_POST['id'] as $k => $v) {
$values[] = array(
'id' => $v,
'title' => $_POST['title'][$k],
'max_vol' => $_POST['max_vol'][$k],
'description' => $_POST['description'][$k],
);
}
print_r($values);
Related
I want to remove array from multidimentional array using base of ID. I tried using foreach loop. But, It is not working.
Any one help me how to remove this?
Thanks.
=> Array :
Array
(
[0] => Array
(
[id] => 11109
[value] => Yes
[field_id] => 234
)
[1] => Array
(
[id] => 11109
[value] => Yes
[field_id] => 237
)
[2] => Array
(
[id] => 11110
[value] => No
[field_id] => 234
)
[3] => Array
(
[id] => 11110
[value] => No
[field_id] => 237
)
[4] => Array
(
[id] => 11111
[value] => No
[field_id] => 237
)
)
From this array, I want to remove array which
field_id is 234 and value is "No" && field_id is 237 and value is
"No".
field_id is 234 and value is "Yes" && field_id is 237 and value is
"Yes".
So, From this array only ID 11111 array is display otherwise all array remove from current array.
Here is my code using I tried to remove array.
foreach ($collection->getData() as $key => $value) {
if(($value['field_id'] == $ids[0] && $value['value'] == "No")){
echo $value['id'];
// exit;
break;
}
echo $value['field_id'];
echo $value['value'];
if(($value['field_id'] == $ids[1] && $value['value'] == "No")){
print_r($collection->getData()[$key]);
unset($collection->getData()[$key]);
unset($collection->getData()[$key-1]);
}
}
You can create a new Multidimensional array , and copy only the values you want to it .
also , when you use break , you get out of the foreach loop completely , i don't think this is the intended behavior , use continue to skip current iteration and test the next element
Is the function getData() returning a copy of the array or a reference? If is is only a copy the unset($collection->getData()[$key]) won't work.
Better you loop over the array as you do, but store all keys you want to delete in side a other array (e.g. $keysToRemove). When the for-each-loop is finished you start to loop the new array $keysToRemove containing all the keys you want to remove and remove then from array.
$keysToRemove = array();
$data = $collection->getData(); // copy or reference?
foreach ($data as $key => $value) {
if(($value['field_id'] == $ids[0] && $value['value'] == "No")){
echo $value['id'].'<br>';
break; // exit the loop? If you want to jump to the next element use "continue"
}
echo $value['field_id'].'<br>';
echo $value['value'].'<br>';
if(($value['field_id'] == $ids[1] && $value['value'] == "No")){
$keysToRemove[$key] = true;
$keysToRemove[$key-1] = true;
}
}
foreach(array_keys($keysToRemove) as $key){
echo '<p>remove key '.$key.' with content <pre>'.print_r($data[$key], true).'</pre></p>';
unset($data[$key]);
}
echo '<p>Result array is<pre>'.print_r($data, true).'</pre></p>';
So you don't manipulate the array your loop use at the moment.
Based on the comment that mentioned its a Magento Collection. I think, You could filter the ids in collection itself so that those are not fetched as part of the collection you want. Like:
$collection = Mage::getModel('your/model')->getCollection();
$collection->addAttributeToFilter('field_id', array('nin' => array(234, 237)));
OR, following if your model is non-eav entity model
$collection = Mage::getModel('your/model')->getCollection();
$collection->addFieldToFilter('field_id', array('nin' => array(234, 237)));
try this code which remove all array value which value is No
$cart = array(
0 => array
(
'id' => 11109,
'value' => 'Yes',
'field_id' => 234
),
1 => array
(
'id' => 11109,
'value' => 'Yes',
'field_id' => 123
),
2 => array
(
'id' => 11110,
'value' => 'No',
'field_id' => 234
),
3 => array
(
'id' => 11110,
'value' => 'No',
'field_id' => 237
),
4 => array
(
'id' => 11111,
'value' => 'No',
'field_id' => 237
),
);
$found = array();
$i = 0;
foreach ($cart as $key => $data) {
if ($data['field_id'] == 234 && $data['value'] == 'No') {
$found[$i]['id'] = $data['id'];
$found[$i]['value'] = $data['value'];
$found[$i]['field_id'] = $data['field_id'];
$i++;
}
}
echo "<pre>";
print_r($found);
then Output Is:
Array
(
[0] => Array
(
[id] => 11111
[value] => No
[field_id] => 234
)
)
I'm trying now for a while to wrap my head around the following:
I've got a form that submits a user defined number of values to a PHP script and I need to write them into a MySQL database.
The form itself is working fine and print_r() shows my values like this:
[items] => Array
(
[1] => Array
(
[option] => 3
[check_1] => 1
)
[2] => Array
(
[option] => 2
[check_1] => 1
)
[17] => Array
(
[check_1] => 1
[check_3] => 1
)
)
There will be one option value and up to ten checkboxes per item. Now I'd need to end up with something like this to write each item to the DB:
INSERT INTO table (item_id, option, check_1, check_2,...)
VALUES ('$ItemID', '$OptionValue', '$Check_1_Value', '$Check_2_Value',...)
My biggest problem is to read out the Item IDs (1,2 and 17 in this case) and get it into variables.
Help at PHP : foreach.
foreach ( $items as $key => $values )
{
// $key => 17 <= this the values you were looking for
// $values => { [check_1] => 1, [check_3] => 1 }
[...]
}
Init array:
$items = array(
1 => array(
"option" => 3,
"check_1" => 1,
),
2 => array(
"option" => 2,
"check_1" => 1,
),
17 => array(
"check_1" => 1,
"check_3" => 1,
),
) ;
Parse array:
foreach( $items as $k1 => $a1 )
{ // should be escape for safety mysql_real_escape() or ...
$dbCols = "item_id";
$dbValues = $k1;
foreach( $a1 as $k2 => $v2 )
{
$dbCols .= ",$k2";
$dbValues .= ",$v2";
}
echo "INSERT INTO `table` ( $dbCols ) VALUES ( $dbValues );\n";
}
Result:
INSERT INTO `table` ( item_id,option,check_1 ) VALUES ( 1,3,1 );
INSERT INTO `table` ( item_id,option,check_1 ) VALUES ( 2,2,1 );
INSERT INTO `table` ( item_id,check_1,check_3 ) VALUES ( 17,1,1 );
I am trying to put content of one array into the same array. Here I have an array $mclass with values such as
Array
(
[0] => stdClass Object
(
[room_id] => 1,3,5
[day] => 1
[class_teacher] => TEA-2014-2
[final_exam_date] => 2015-09-21
)
)
You can see I have room_id index with 1,3,5 value. Now, I want to explode the room_id and get duplicate of same array index data with change of room_id and push into the array. and finally delete the current array index such as [0]. Here I want the final result as.
Array
(
[0] => stdClass Object
(
[room_id] => 1
[day] => 1
[class_teacher] => TEA-2014-2
[final_exam_date] => 2015-09-21
)
[1] => stdClass Object
(
[room_id] => 3
[day] => 1
[class_teacher] => TEA-2014-2
[final_exam_date] => 2015-09-21
)
[2] => stdClass Object
(
[room_id] => 5
[day] => 1
[class_teacher] => TEA-2014-2
[final_exam_date] => 2015-09-21
)
)
Here is my code for the same:
if(count($mclass)>0)
{
foreach($mclass as $mclasskey=>$mclass_row)
{
/* Room ID Calculation */
if(isset($mclass[$mclasskey]))
{
$temp_room_id = explode(',',$mclass_row->room_id);
if(count($temp_room_id)>1)
{
foreach($temp_room_id as $trkey=>$tr)
{
if(!in_array($temp_room_id[$trkey], $morning_class_semester))
{
array_push($morning_class_semester,$temp_room_id[$trkey]);
}
}
if(count($morning_class_semester)>0)
{
foreach($morning_class_semester as $mcskey=>$mcs)
{
$index_count = count($new_test);
$test[$index_count] = $mclass[$mclasskey];
$test[$index_count]->room_id = $morning_class_semester[$mcskey];
array_push($new_test,$test[$index_count]);
}
unset($mclass[$mclasskey]);
}
}
}
}
}
The code below does what you're looking for using only arrays. So you'll have to change the array access operators to -> since you're accessing an object. I'd do so, but it would break the example, so I'll leave that up to you.
Code Explained:
Loop through array selecting each subarray (object in your case), explode on the $item('room_id') ... ($item->room_id in your case) ... and create sub arrays, via loop, from that using the data from the original using each key. Remove the original item (which has the combined room_ids) and combine the placeholder and original array.
<?php
//Establish some data to work with
$array = array(
array(
"room_id" => "1,3,5",
"day" => 1,
"class_teacher" => "TEA-2014-2",
"final_exam_date" => "2015-09-21",
));
foreach ($array as $key => $item) {
$placeholder = array();
$ids = explode(',',$item['room_id']);
if (count($ids) > 1) {
foreach ($ids as $id) {
$push = array(
'room_id' => $id,
'day' => $item['day'],
'class_teacher' => $item['class_teacher'],
'final_exam_date' => $item['final_exam_date']
);
array_push($placeholder, $push);
}
$array = array_merge($array, $placeholder);
unset($array[$key]);
}
}
var_dump($array);
?>
I have 2 arrays:
Array
(
[0] => Array
(
[id] => 1
[fieldname] => banana
[value] => yellow
)
)
Array
(
[0] => Array
(
[id] => 1
[fieldname] => rome
[value] => city
)
[1] => Array
(
[id] => 2
[fieldname] => bla
[value] => yes
)
)
I want to create a new array that contains only elements where "id" is different. In other words I want to get this output:
Array
(
[0] => Array
(
[id] => 2
[fieldname] => bla
[value] => yes
)
)
[id] => 2 was the only different [id] so I keep it.
Said that I've already managed to achieve my goal with an inefficient pile of foreach, if statements and temp variables. I really don't want to use a wall of code for this very small thing so I started to look for a native PHP function with no success. What's the easiest way to get the result? Is it possible that I strictly need to use a foreach with so many if?
You can use array_udiff with a function.
Computes the difference of arrays by using a callback function for
data comparison.
Returns an array containing all the values of the first array that are not
present in any of the other arguments.
The code:
// Setup two arrays as per your question
$array1 = array (
'0' => array (
'id' => '1',
'fieldname' => 'banana',
'value' => 'yellow',
)
);
$array2 = array (
'0' => array (
'id' => '1',
'fieldname' => 'rome',
'value' => 'city',
),
'1' => array (
'id' => '2',
'fieldname' => 'bla',
'value' => 'yes',
)
);
// Setup the callback comparison function
function arrayCompare($array2, $array1) {
return $array2['id'] - $array1['id'];
}
// Use array_udiff() with the two arrays and the callback function
$arrayDiff = array_udiff($array2, $array1, 'arrayCompare');
print_r($arrayDiff);
The above code returns the following:
Array (
[1] => Array (
[id] => 2
[fieldname] => bla
[value] => yes
)
)
This should do it. Not super short and it does use a temporary variable, so perhaps not what you were looking for. I've named the two arrays one and two.
$ids = array();
$result = array();
foreach ($one as $x) {
$ids[$x['id']] = 1; //This way, isset($x['id']) vill return true
}
foreach ($two as $x) {
if (!isset($ids[$x['id']])) {
$result[] = $x;
}
}
I would be surprised if there wasn't an even more compact way to do it.
EDIT: This is an alternative variant with nested for each. Not particularly short either.
$result = array();
foreach ($one as $x) {
foreach ($two as $y) {
if ($x['id'] == $y['id']) {
//A match, lets try the next $x
continue 2;
}
}
//No matching id in $two
$result[] = $x;
}
I have got this array
Array
(
[0] => Array
(
[category_name] => Dessert1
[totalOrders] => 3
)
[1] => Array
(
[category_name] => Dessert1
[totalOrders] => 1
)
[2] => Array
(
[category_name] => Category 3
[totalOrders] => 1
)
)
and I want to convert it into this array
Array
(
[0] => Array
(
[category_name] => Dessert1
[totalOrders] => 4
)
[1] => Array
(
[category_name] => Category 3
[totalOrders] => 1
)
)
It is really rather simple. You just loop over your data and pick out the unique categories. When there are duplicates add the orders to the category's total.
// The stuff from your post
$data = array(
array('category_name' => 'Dessert1', 'totalOrders' => 3),
array('category_name' => 'Dessert1', 'totalOrders' => 1),
array('category_name' => 'Category 3', 'totalOrders' => 1),
);
// Auxiliary variable
$result = array();
// Go over the data one by one
foreach ($data as $item)
{
// Use the category name to identify unique categories
$name = $item['category_name'];
// If the category appears in the auxiliary variable
if (isset($result[$name]))
{
// Then add the orders total to it
$result[$name]['totalOrders'] += $item['totalOrders'];
}
else // Otherwise
{
// Add the category to the auxiliary variable
$result[$name] = $item;
}
}
// Get the values from the auxiliary variable and override the
// old $data array. This is not strictly necessary, but if you
// want the indices to be numeric and in order then do this.
$data = array_values($result);
// Take a look at the result
var_dump($data);