How to add $_POST values in a multi-dimensional array (PHP)? - php

I know there may be sources for this out there but I'v tried everything and I'm still not getting the proper solution. That why I'm asking for you help out here.
I have a $_POST array and I want to put values in a an array. Here is the final out I want:
$response = [
['category' => 2, 'value' => "june"],
['category' => 5, 'value' => "may"],
['category' => 8, 'value' => "april"]
]
Here is the catch,the $_POST contains a value of an integer with a space in between and then a string eg '2 june', '5 may' etc
When I get this value, I split it using explode then I try to add the individual values into the response array. This is only adding just one result.
What I tried:
$response = [];
foreach ($_POST as $key => $value) {
$split = explode(" ", $value);
$result = ['category' => $split[0], 'value' => $split[1]];
$response[] = $result;
}
for some reason, the results are not as suggested above. Any ideas and suggestion will be appreciated.

Basically, problem is in the $_POST. This is global array with submitted key-values data. You should NOT use
foreach ($_POST as $key => $value) {
for parsing your data without any checks. This data is submitted by user, and not always they will have format you're waiting for.
For example, if you have a variable "dates" in your HTML form, you should be ready that $_POST['dates'] will be an array of all of your '5 june', '7 july', etc. Don't forget to check and validate all user data you received. It's important by security reason too.
Your code (foreach body, without condition) is ok, I've checked it. Try to set print_r() before explode() you will see that your're working with an array, not with a string.

Your question doesn't have an issue with processing the data into the correct resulting array. The onus falls on $_POST not holding the expected data.
All answers to this question are powerless to fix your $_POST data because no html form was supplied with your question. The only potential value that can be offered is to refine your array building process.
Here are two methods that improve your process by reducing the number of declared variables:
Demonstration uses $a=array('2 june','5 may','8 april'); to represent your $_POST array.
One-liner in a foreach loop:
foreach($a as $v){
$r[]=array_combine(["category","value"],explode(" ",$v));
}
One-liner with no loop:
$r=array_map(function($v){return array_combine(["category","value"],explode(" ",$v));},$a);
Using either process the resulting $r will be:
array (
0 =>
array (
'category' => '2',
'value' => 'june',
),
1 =>
array (
'category' => '5',
'value' => 'may',
),
2 =>
array (
'category' => '8',
'value' => 'april',
),
)
References for used functions:
explode() , array_combine() , array_map()

Try this one:
$response = [];
// just for example use this one
$data = "2 june, 5 may, 7 july";
$temp = explode(",", $data);
// and you can use this one for your case
/*$data = $_POST['var_name']; // var_name is your variable name from $_POST
$temp = explode(",", $data);*/
foreach ($temp as $key => $value) {
$split = explode(" ", trim($value));
foreach ($split as $val) {
$result = ['category' => $split[0], 'value' => $split[1]];
}
$respon[] = $result;
}
echo "<pre>";
echo print_r($respon);
echo "</pre";
the output:
Array
(
[0] => Array
(
[category] => 2
[value] => june
)
[1] => Array
(
[category] => 5
[value] => may
)
[2] => Array
(
[category] => 7
[value] => july
)
)

$response = array();
foreach ($_POST as $key => $value) {
$split = '';
$split = explode(" ", $value);
$result = array('category' => $split[0], 'value' => $split[1]);
$response[] = $result;
}

Related

PHP, how do you change the key of an array element?

Hello guys, and Happy new year!
How can I add keys to this array
$my_array = array( [0] => 703683 [1] => 734972 [2] => 967385 )
So I would like to add a single key to all values example:
$copy_array = array( ['id'] => 703683 ['id'] => 734972 ['id'] => 967385 )
I tried this solution:
new_arr = [];
foreach ($my_array as $key => $value) {
// code..
$new_arr['id'] = $value ;
}
Output:
( [id] => 703683 )
You can't. An array key is identifying the element it represents. If you set 'id' to be a specific value, then you set it to be another specific value, then you override the former with the latter. Having separate values as ids is self-contradictory anyway, unless they identify different objects. If that's the case, then you can change your code to
new_arr = [];
foreach ($my_array as $key => $value) {
// code..
$new_arr[] = ['id' => $value] ;
}
or even
new_arr = [];
foreach ($my_array as $key => $value) {
// code..
$new_arr[$value] = ['id' => $value] ;
}
but the only use of such a change would be if they have other attributes, which are not included in the codes above, since your question does not provide any specific information about them if they exist at all. If everything is only an id, then you might as well leave it with numeric indexes.

How to remove a array from an array by comparing it with another array?

I've 2 array as below. One array is a 2 dimensional array($array_1) and another is a simple array ($array_2). This $array_1 as a key called private_name in each array and $array_2 has a list of private_key values. I want to keep the array from $array_1 which matches with $array_2.
$array_1 = [
[0] => ['id'=>12, 'private_name' => 'name12', 'age' => '23'],
[1] => ['id'=>2, 'private_name' => 'name2', 'age' => '23'],
[2] => ['id'=>9, 'private_name' => 'name1', 'age' => '23'],
[3] => ['id'=>11, 'private_name' => 'name11', 'age' => '23'],
.
.
.
[999] => ['id'=>999, 'private_name' => 'name999', 'age' => '23'],
];
$array_2 = ['name1', 'name2', 'name3',....];
So i wante remove array contents from $array_1 which matches with $array_2. Currently am using the below method but it takes a lot of time as there are 14k+ array values in $array_1. Is there any soulution for this which just uses 1 line to solve the above. I want a solution like
$newVal = array_intersect(array_column($array_1, 'private_name'), $array_2);
Current am doing like below which takes a lot of time
$results = array();
$count = 0;
if (count($array_1) > 0) {
foreach ($array_1 as $row) {
foreach ($row as $col => $val) {
foreach ($array_2 as $key3 => $pvt_name) {
if (strcmp($row['private_name'], $array_1) == 0) {
$results[$count][$col] = $val;
}
}
}
$count++;
}
}
Any help is much appreciated. Thank you
This can easily be done using array_filter.
$filtered_array = array_filter($array_1, function($item) use($array_2) {
return !in_array($item['private_name'], $array_2);
});
var_dump($filtered_array);
The callback function needs to return true to keep the item in the result, false to discard it. That is done here by checking if the private_name value of the item is contained in your second array - and the result of that negated, because you only want to keep those that don’t match.

Search PHP array of arrays using an array value and then update other array values in the matching array

I have a string stored in WordPress MySQL database Meta field as serialized string of array of arrays like this:
a:4:{i:0;a:8:{s:19:"ab-variation-letter";s:1:"B";s:18:"ab-variation-title";s:6:"bbbbbb";s:28:"ab-variation-wysiwyg-editor-";s:12:"bbbbbbbbbbbb";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:1;a:8:{s:19:"ab-variation-letter";s:1:"C";s:18:"ab-variation-title";s:5:"ccccc";s:28:"ab-variation-wysiwyg-editor-";s:17:"ccccccccccccccccc";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:2;a:8:{s:19:"ab-variation-letter";s:1:"D";s:18:"ab-variation-title";s:8:"dddddddd";s:28:"ab-variation-wysiwyg-editor-";s:1:"d";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:3;a:8:{s:19:"ab-variation-letter";s:1:"E";s:18:"ab-variation-title";s:8:"eeeeeeee";s:28:"ab-variation-wysiwyg-editor-";s:30:"eeeeeee eeeeeeeeeeeee eeeeeeee";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}}
When I unserialize that string above it looks like this below...
array (
0 =>
array (
'ab-variation-letter' => 'B',
'ab-variation-title' => 'bbbbbb',
'ab-variation-wysiwyg-editor-' => 'bbbbbbbbbbbb',
'ab-variation-conversion-count' => '',
'ab-variation-views' => '',
'ab-variation-start-date' => '',
'ab-variation-end-date' => '',
'ab-variation-winner' => '',
),
1 =>
array (
'ab-variation-letter' => 'C',
'ab-variation-title' => 'ccccc',
'ab-variation-wysiwyg-editor-' => 'ccccccccccccccccc',
'ab-variation-conversion-count' => '',
'ab-variation-views' => '',
'ab-variation-start-date' => '',
'ab-variation-end-date' => '',
'ab-variation-winner' => '',
),
2 =>
array (
'ab-variation-letter' => 'D',
'ab-variation-title' => 'dddddddd',
'ab-variation-wysiwyg-editor-' => 'd',
'ab-variation-conversion-count' => '',
'ab-variation-views' => '',
'ab-variation-start-date' => '',
'ab-variation-end-date' => '',
'ab-variation-winner' => '',
),
3 =>
array (
'ab-variation-letter' => 'E',
'ab-variation-title' => 'eeeeeeee',
'ab-variation-wysiwyg-editor-' => 'eeeeeee eeeeeeeeeeeee eeeeeeee',
'ab-variation-conversion-count' => '',
'ab-variation-views' => '',
'ab-variation-start-date' => '',
'ab-variation-end-date' => '',
'ab-variation-winner' => '',
),
)
based on this array of arrays above. I want to be able to search for the array that has ab-variation-letter' => 'C' and then be able to update any of the other array key values on that matching array. When done I will need to re-serialize back into a string so I can save it back to the Database table again.
I want to build this PHP function below to be able to take my serialized string of array of arrays and search those arrays for an array that has a key/value matching the passed in $array_key string and then update another keyvalue in that same array and then reserialize the whole thing again.
function updateAbTestMetaData($post_id, $meta_key, $meta_value, $array_key, $new_value){
//get serialized meta from DB
$serialized_meta_data_string = 'a:4:{i:0;a:8:{s:19:"ab-variation-letter";s:1:"B";s:18:"ab-variation-title";s:6:"bbbbbb";s:28:"ab-variation-wysiwyg-editor-";s:12:"bbbbbbbbbbbb";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:1;a:8:{s:19:"ab-variation-letter";s:1:"C";s:18:"ab-variation-title";s:5:"ccccc";s:28:"ab-variation-wysiwyg-editor-";s:17:"ccccccccccccccccc";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:2;a:8:{s:19:"ab-variation-letter";s:1:"D";s:18:"ab-variation-title";s:8:"dddddddd";s:28:"ab-variation-wysiwyg-editor-";s:1:"d";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:3;a:8:{s:19:"ab-variation-letter";s:1:"E";s:18:"ab-variation-title";s:8:"eeeeeeee";s:28:"ab-variation-wysiwyg-editor-";s:30:"eeeeeee eeeeeeeeeeeee eeeeeeee";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}}';
//un-serialize meta data string
$meta_data_arrays = unserialize($serialized_meta_data_string);
// search array of arrays $meta_data_arrays for array that has a key == $array_key // 'ab-variation-letter' === 'D'
// update the value of any other key on that matching array
// re-serialize all the data with the updated data
}
The end result should allow me to find the array with key 'ab-variation-letter' === 'C' and update the key/value in that matching array with key 'ab-variation-title' and update its current value from 'ccccc' to 'new value' and then re-serialize the whole entire array of arrays back into the original string with only the updated array data updated/
Perhaps throwing together a recursive function that can make use of calling itself could come in handy:
function replaceArrayKeyValue(array &$arr, $whereKey, $whereValue, $replacement) {
$matched = false;
$keys = array_keys($arr);
for ($i = 0; $i < count($keys); $i++)
{
$key = $keys[$i];
if (is_string($arr[$key])) {
if ($key === $whereKey && $arr[$key] === $whereValue) {
if (is_array($replacement)) {
$arr = array_replace_recursive($arr, $replacement);
} else {
$arr[$key] = $replacement;
}
$matched = $key;
break;
}
} else if (is_array($arr[$key])) {
$m = replaceArrayKeyValue($arr[$key], $whereKey, $whereValue, $replacement);
if ($m !== false) {
$matched = $key.'.'.$m;
break;
}
}
unset($key);
}
unset($keys);
return $matched;
}
With the above function, you pass through the source array ($arr), the key you're looking for ($whereKey), the value that it should match ($whereValue) and the replacement value ($replacement).
If $replacement is an array, I've got a array_replace_recursive in place to perform a recursive replacement, allowing you to pass in the changes you'd like to make to the array. For example, in your case:
$data = unserialize(...);
$matchedKey = replaceArrayKeyValue($data, 'ab-variation-letter', 'C', [
'ab-variation-title' => 'My New Title'
]);
$serialized = serialize($data);
You could replace this with array_recursive if you're not wanting the changes to occur further down any nested child arrays.
When using this function, the $data array is modified directly. The result of the function is a joint string of the key path to that value, in this case:
echo $matchedKey; // Result: 1.ab-variation-letter
If you echo print_r($data, true), you get the intended result:
Array (
[0] => Array( ... )
[1] => Array
(
[ab-variation-letter] => C
[ab-variation-title] => My New Title
[ab-variation-wysiwyg-editor-] => ccccccccccccccccc
[ab-variation-conversion-count] =>
[ab-variation-views] =>
[ab-variation-start-date] =>
[ab-variation-end-date] =>
[ab-variation-winner] =>
)
[2] => Array( ... )
[3] => Array( ... )
)
I got it working after some playing around with this code below. Open to other versions as well thanks
$serialized_meta_data_string = 'a:4:{i:0;a:8:{s:19:"ab-variation-letter";s:1:"B";s:18:"ab-variation-title";s:6:"bbbbbb";s:28:"ab-variation-wysiwyg-editor-";s:12:"bbbbbbbbbbbb";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:1;a:8:{s:19:"ab-variation-letter";s:1:"C";s:18:"ab-variation-title";s:5:"ccccc";s:28:"ab-variation-wysiwyg-editor-";s:17:"ccccccccccccccccc";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:2;a:8:{s:19:"ab-variation-letter";s:1:"D";s:18:"ab-variation-title";s:8:"dddddddd";s:28:"ab-variation-wysiwyg-editor-";s:1:"d";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:3;a:8:{s:19:"ab-variation-letter";s:1:"E";s:18:"ab-variation-title";s:8:"eeeeeeee";s:28:"ab-variation-wysiwyg-editor-";s:30:"eeeeeee eeeeeeeeeeeee eeeeeeee";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}}';
$update_on_key = 'ab-variation-title';
$ab_version = 'C';
$new_value = 'new variation title on variation C';
$new_data = updateMetaArrayData($serialized_meta_data_string, $update_on_key, $ab_version, $new_value);
echo '<pre>';
echo $new_data;
function updateMetaArrayData($serialized_meta_data_string, $update_on_key, $ab_version, $new_value){
$new_meta_data_arrays = array();
//un-serialize meta data string
$meta_data_arrays = unserialize($serialized_meta_data_string);
foreach($meta_data_arrays as $key => $value){
$new_meta_data_arrays[$key] = $value;
if(isset($value['ab-variation-letter']) && $value['ab-variation-letter'] == $ab_version){
$new_meta_data_arrays[$key][$update_on_key] = $new_value;
}
}
echo '<pre>';
print_r($new_meta_data_arrays);
$new_serialized_meta = serialize($new_meta_data_arrays);
return $new_serialized_meta;
}

How to unset dynamically generated multidimensional array

I am trying to delete an array whereby one of its values..(time) meet a specific condition. \The code I'm currently working with looks like this:
foreach($_SESSION as $key) {
foreach($key['time'] as $keys=>$value){
if(condition){
unset($key);
}
}
}
The array looks like this.
Array
(
[form1] => Array
(
[hash] => lFfKBKiCTG6vOQDa8c7n
[time] => 1401067044
)
[form5] => Array
(
[hash] => TTmLVODDEkI1NrRnAbfB
[time] => 1401063352
)
[form4] => Array
(
[hash] => XCVOvrGbhuqAZehBmwoD
[time] => 1401063352
)
I tried to adapt solutions from these pages but didn't work.
Remove element in multidimensional array and save
PHP - unset in a multidimensional array
PHP How to Unset Member of Multidimensional Array?
If you want to unset the values inside it, a simple single foreach will suffice. Consider this example:
$values = array(
'form1' => array('hash' => 'lFfKBKiCTG6vOQDa8c7n', 'time' => 1401067044),
'form5' => array('hash' => 'TTmLVODDEkI1NrRnAbfB', 'time' => 1401063352),
'form4' => array('hash' => 'XCVOvrGbhuqAZehBmwoD', 'time' => 1401063352),
);
$needle = 1401067044;
foreach($values as $key => &$value) {
if($value['time'] == $needle) {
// if you want to remove this key pair use this
unset($values[$key]['time']);
// if you just want to remove the value inside it
$value['time'] = null;
// if you want to remove all of this entirely
unset($values[$key]);
}
}
Fiddle
Unsetting in a for loop can lead to issues, its easier and better to use array_filter which is optimized for this kind of problem. Here is how to do it with your example. ideone running code
<?php
$ar = Array(
"form1" => Array
(
"hash" => 'lFfKBKiCTG6vOQDa8c7n',
"time" => '1401067044'
),
"form5" => Array
(
"hash" => 'TTmLVODDEkI1NrRnAbfB',
"time" => '1401063352'
),
"form4" => Array
(
"hash" => 'XCVOvrGbhuqAZehBmwoD',
"time" => '1401063352'
)
);
$condition = '1401067044';
$newArray = array_filter($ar, function($form) use ($condition) {
if (!isset($form['time'])) {
return true;
}
return $form['time'] != $condition;
});
var_export($newArray);
array_filter
Assuming your values are stored in $_SESSION
foreach($_SESSION as $key => $value) {
if(isset($value['time']) && $value['time'] < 1401063352) {
unset($_SESSION[$key]);
}
}
If you are storing your values in $_SESSION you may want to consider storing them in a subfield like $_SESSION['myForms'] so if you need to add other values to your session you can easily access only the values you need.
You need to do
unset($_SESSION[$key])
However as mentioned by Victory, array_filter is probably a better approach to this.

what should i do to get array like this in php?

I have one array as below :
Array
(
[Sep] => Array
(
[Support Help Desk] => 24.67
[Development] => 7.74
[Consulting Services] => 4.04
)
[Oct] => Array
(
[Support Help Desk] => 14.38
[Business Activity] => 1.92
[Maintenance Tasks] => 1.00
[Development] => 2.11
)
)
and i want array like this :
Array
(
[Support Help Desk] => 24.67,14.38
[Development] => 7.74,2.11
[Consulting Services] => 4.04,0
[Business Activity] => 0,1.92
[Maintenance Tasks] => 0,1.00
)
I am using php with zend framework.
But i don't know what method should i use to get array like this ?
can anyone please guide me ?
-
Thanks in advance.
Third time lucky! I missed out on some subtleties in the question originally. Try the following code - it's a bit loopy but it should work for you.
I am assuming that your original array is called $data.
// first we need to 'normalise' or fill in the blanks in the contents of the sub array
// get a unique list of all the keys shared - doing it manually here
$keys = ['Support Help Desk', 'Business Activity', 'Maintenance Tasks', 'Development', 'Consulting Services'];
// create a default array with $keys, assigning 0 as the value of each
$default = array_fill_keys($keys, 0);
// next fill in the blanks...
// get the diff (missing keys) between the current element and the default array
// merge the missing key/value pairs
array_walk($data, function(&$month, $key, $default) {
$diff = array_diff_key($default, $month);
$month = array_merge($diff, $month);
}, $default);
// now the array is normalised
// flatten the array... where there are duplicate values for a key, and
// there will be in all cases now including default values
// a sub array is created
$merged = call_user_func_array('array_merge_recursive', $data);
// finally loop over the merged array
// and implode each array of values into a comma separated list
foreach ($merged as &$element) {
if (is_array($element)) {
$element = implode(', ', $element);
}
}
// done :)
var_dump($merged);
Yields:
array (size=5)
'Business Activity' => string '0, 1.92' (length=7)
'Maintenance Tasks' => string '0, 1' (length=4)
'Support Help Desk' => string '24.67, 14.38' (length=12)
'Development' => string '7.74, 2.11' (length=10)
'Consulting Services' => &string '4.04, 0' (length=7)
Hope this helps :)
EDIT
Live example at eval.in
Let's say your array is stored in $main_arr and result array is $result_arr.
$result_arr = array();
foreach ($main_arr as $month) {
foreach ($month as $key => $val) {
if (!isset($result_arr[$key])) {
$result_arr[$key] = array($val);
} else {
array_push($result_arr[$key], $val);
}
}
}
foreach ($result_arr as $key => $val) {
$result_arr[$key] = implode(', ', $val);
}
print_r($result_arr); //Final output.

Categories