Unserialize from MySQL into a Multi-dimensional PHP array - php

I have a PHP/MySQL e-commerce site that is placing order detail information into a serialized array alongside customer address info.
I want to be able to pull out the order items field, unserialize it and then combine the order items into one master array of ALL ordered items that can be manipulated in order to count how many orders of a specific product have been made.
The arrays look like this when I print_r the unserialized rows. Below are two order arrays, one with 3 products, and the second with only one.
The array values are ID #, SKU #, Quantity, Product Name, Price.
I want to be able to combine ALL orders into one array and then sum the total quantities for each unique ID or SKU number.
I realize this type of thing is drop dead simple if the data was clean in MySQL, but such is life. Any thoughts on how to manipulate these arrays would be truly appreciated.
In this case want to end up with 4 arrays, with the 629/01-3600 ones being combined such that the quantity value is now 2
Many thanks.
Array
(
[0] => Array
(
[1] => 488
[5] => 23-1000
[2] => 3
[3] => PRODUCT NAME
[4] => 2.50
)
[1] => Array
(
[1] => 423
[5] => 24-2300
[2] => 1
[3] => PRODUCT NAME
[4] => 3.50
)
[2] => Array
(
[1] => 506
[5] => 23-2800
[2] => 1
[3] => PRODUCT NAME
[4] => 2.50
)
[3] => Array
(
[1] => 629
[5] => 01-3600
[2] => 1
[3] => PRODUCT NAME
[4] => 7.50
)
)
Array
(
[0] => Array
(
[1] => 629
[5] => 01-3600
[2] => 1
[3] => PRODUCT NAME
[4] => 7.50
)
)
EDIT:
I wanted to add what eventually did what I was looking for
foreach($query->result as $row)
{
$items[] = unserialize( $row['FIELDNAME'] );
}
foreach($items as $item)
{
foreach($item as $order)
{
if( isset($output_array[$order[1]]) )
{
$output_array[$order[1]]['quantity'] += $order[2];
}
else
{
$output_array[$order[1]] = array (
'name' => $order[3],
'quantity' => $order[2],
'sku' => $order[5]
);
}
}
}
I then used this sorting function to sort on the quantity: http://www.php.net/manual/en/function.sort.php#99419

This is a little bit of code so I've separated it into chunks.
This is my recreation of your two arrays. The last line puts them into one.
$items = array(
array(
1 => 488,
5 => '23-1000',
2 => 3,
3 => 'PRODUCT NAME',
4 => 2.50
),
array(
1 => 423,
5 => '24-2300',
2 => 1,
3 => 'PRODUCT NAME',
4 => 3.50
),
array(
1 => 506,
5 => '23-2800',
2 => 1,
3 => 'PRODUCT NAME',
4 => 2.50
),
array(
1 => 629,
5 => '01-3600',
2 => 1,
3 => 'PRODUCT NAME',
4 => 7.50
)
);
$array_2 = array(
array(
1 => 629,
5 => '01-3600',
2 => 1,
3 => 'PRODUCT NAME',
4 => 7.50
)
);
// Put the two arrays together (master array)
$new_array = array_merge($items, $array_2);
Next, we create two arrays to that will use the SKU# and another for the IDs.
// What the items will be sorted by
$skus = array();
$ids = array();
The more complicated part
// Loop through the combined items
foreach( $new_array as $item ) {
/**
* Check if the item's SKU number
* has been added to the $skus array.
*
* If it has then add the old qty with the current item's
*
* Else, the item hasn't been added yet,
* then add the entire item to the list
*/
if( isset($skus[$item[5]]) ) {
// If it exists, then add the new qty
$skus[$item[5]][2] += $item[2];
}else {
// If it doesn't exist, then append it to the array
$skus[$item[5]] = $item;
}
// Do the same thing as above
// except for the id numbers
if( isset($ids[$item[1]]) ) {
// If it exists, then add the new qty
$ids[$item[1]][2] += $item[2];
}else {
// If it doesn't exist, then append it to the array
$ids[$item[1]] = $item;
}
}
Make sure everything is the way you want it
echo '<h2>SKU Numbers</h2>';
echo '<pre>';
print_r($skus);
echo '</pre>';
echo '<h2>ID Numbers</h2>';
echo '<pre>';
print_r($ids);
echo '</pre>';
Hope this helps.
EDIT
For this code to work during the actual loop, you can try something like this. While I'm not completely sure if this will work out of the box, it should be a good place to start.
// What the items will be sorted by
$skus = array();
$ids = array();
foreach( $result as $row ) {
$row = unserialize($row);
/**
* MODIFIED
*
* Check if the $row's SKU number
* has been added to the $skus array.
*
* If it has then add the old qty with the current $row's qty
*
* Else, the $row hasn't been added yet,
* then add the entire $row to the list
*/
if( isset($skus[$row[5]]) ) {
// If it exists, then add the new qty
$skus[$row[5]][2] += $row[2];
}else {
// If it doesn't exist, then append it to the array
$skus[$row[5]] = $row;
}
// Do the same thing as above
// except for the id numbers
if( isset($ids[$row[1]]) ) {
// If it exists, then add the new qty
$ids[$row[1]][2] += $row[2];
}else {
// If it doesn't exist, then append it to the array
$ids[$row[1]] = $row;
}
}

Related

How to use multidimensional array PHP

What i want is:
Array-one (the product db array):
Product id
Cat name
Array-two (the category db array):
cat id
Cat name
if Array-one: cat name is equal to Array-two: cat name add all product ids under the cat id
//this foreach is loop to products
foreach($objects as $object) {
//get cat name from product db
$cat_name_product = $object['values']['17'];
// this foreach is loop to cat db
foreach($cat_db as $cat_object) {
// get cat name from cat db
$cat_name_cat_table = $cat_object['values'][2];
// if cat from product DB is equal to cat name from cat DB
if($cat_name_product == $cat_name_cat_table){
$cat_name_product_id = $object['id'];
$cat_name_db_id = $cat_object['id'];
// Add products ids to a specfic row id from cat
$cat_db_row[$cat_name_db_id][] = $cat_name_product_id;
}
}
}
Result array:
Array
(
[45156381272] => Array
(
[0] => 44990952854
)
[45002415686] => Array
(
[0] => 45054787942
[1] => 45056971448
[2] => 45049917079
[3] => 45056971449
)
)
what i want:
Array
(
[0] => (
[cat_id] => 45156381272
[product_ids] => Array
(
[0] => 44990952854
)
)
[1] =>
[cat_id] => 45156381272
[product_ids] => Array
(
[0] => 45054787942
[1] => 45056971448
[2] => 45049917079
[3] => 45056971449
)
)
How do i do this?
My code gets the desired result:
Input Data:
$arrayProducts = [["Cat_name" => 'cat example 1', "product_id" => 44990952854],
["Cat_name" => 'cat example 2', "product_id" => 44990952854],
["Cat_name" => 'cat example 2', "product_id" => 44990952854],
["Cat_name" => 'cat example 2', "product_id" => 44990952854],
["Cat_name" => 'cat example 2', "product_id" => 44990952854]];
$arrayCategories = [["cat_id" => 45156381272, "Cat_name" => 'cat example 1'],
["cat_id" => 45002415686, "Cat_name" => 'cat example 2']];
Code:
I iterate first the categories array and then (inner) the products arrays.
<?php
$resultArray = array();
foreach($arrayCategories as $key => $element2) {
$resultArray[$key] = array("cat_id" => $element2["cat_id"], "products_ids" => array());
foreach($arrayProducts as $element1) {
if($element1["Cat_name"] == $element2["Cat_name"]) {
$resultArray[$key]["products_ids"][] = $element1["product_id"];
}
}
}
?>
Output ($resultArray)
array ( 0 => array ( 'cat_id' => 45156381272, 'products_ids' => array ( 0 => 44990952854, ), ), 1 => array ( 'cat_id' => 45002415686, 'products_ids' => array ( 0 => 44990952854, 1 => 44990952854, 2 => 44990952854, 3 => 44990952854, ), ), );
Keep using the category ID as array index, while you are building the array. That is (IMHO) the most efficient way to accumulate the data under that ID - otherwise, you would have to search your array for the index of the item with the category ID of the current record all the time.
Add another dimension below that, for the category ID, and the product IDs:
$cat_db_row[$cat_name_db_id]['cat_id'] = $cat_name_db_id;
$cat_db_row[$cat_name_db_id]['product_ids'][] = $cat_name_product_id;
(Technically, that first line overwrites $cat_db_row[$cat_name_db_id]['cat_id'] again and again - but since it is always with the same category ID value, that doesn’t matter. You could do a check whether $cat_db_row[$cat_name_db_id]['cat_id'] is already set first, but that would have rather little point.)
“Reset” the array keys afterwards, when you are done filling the array, using
$cat_db_row = array_values($cat_db_row);
This will throw away all the existing (top-level) array keys, and re-index the array numerically, starting at 0.

require value and respective key from array in php

I have a a array like below and i want min value and it's index for searching tax class id
Array
(
[tax_class_id] => Array
(
[0] => 12
[1] => 13
[2] => 13
)
[price] => Array
(
[0] => 6233
[1] => 3195
[2] => 19192
)
)
and i am searching least price and respective key in tax_class_id. In this Senario, i require lowest in price i.e 3195 and tax_id - 13 i.e key [1]
My Code is
$prod_total = array();
for($i = 1;$i <= $chunk;$i++){
if($i == 1) {
$min_product_amt = min($product_amt['price']);
$index = array_search($min_product_amt, $product_amt);
$product_total = $min_product_amt;
//ceil Round numbers up to the nearest integer
$prod_total['price'] = ceil($product_total * $discount/100);
$prod_total['tax_id'] = $product_amt['tax_class_id'];
//Remove the first element from an array
array_shift($product_amt['price']);
array_shift($product_amt['tax_class_id']);
} else {
$second_min_product_amt = min($product_amt['price']);
$index = array_search($min_product_amt, $product_amt);
$product_total = $second_min_product_amt;
$prod_total['price'] = ceil($product_total * $discount/100);
$prod_total['tax_id'] = $product_amt['tax_class_id'];
array_shift($product_amt['price']);
array_shift($product_amt['tax_class_id']);
}
}
print_r($prod_total);
die;
$array=Array
(
'tax_class_id' => Array
(
0 => 12,
1 => 13,
2 => 13
),
'price' => Array
(
0 => 6233,
1 => 3195,
2 => 19192
)
);
$minValue= min($array['price']);
$minKey=array_keys($array['price'], $minValue);
$tax_id=$array['tax_class_id'][$minKey[0]];
echo $tax_id;
This code will work for your issue. First i get the minimum value of nested array price and then it's associated key. After that i just access the nested array tax_class_id and get the value of the field i need like accessing every array.
$data = [
"tax_class_id" => [
12,
13,
13
],
"price" => [
6233,
3195,
19192
]
];
$lowestFound;
foreach($data["price"] as $i => $price){
if(!$lowestFound || $lowestFound[1] > $price)
$lowestFound = [$i,$price];
}
echo $data["tax_class_id"][$lowestFound[0]];
This code get tax_class_id of lowest price key in one cycle.
I think array_column gives you a nice output.
$array=Array
(
'tax_class_id' => Array(
0 => 12,
1 => 13,
2 => 13
),
'price' => Array(
0 => 6233,
1 => 3195,
2 => 19192
)
);
// Find minimum value
$min= min($array['price']);
// Find key of min value
$Key=array_search($min, $array['price']);
// Extract all values with key[min value]
$new = array_column($array, $Key);
Var_dump($new);
The output in $new will now be
array(2) {
[0]=> int(13)
[1]=> int(3195)
}
Basically both of the values you are looking for.
https://3v4l.org/NsdiS

How to Remove duplicate values from Multidimentional array with single unique value in all array

I have multi-dimentional array like below,
$product = array(
"2e471a22b1b994a7cb3f3a40cee9fba2" => array (
"product" => 6004,
"unique_key" => 3a8a5cb029ee3b92cfc90de23e2329ab,
"product_id" => 51,
"line_total"=>99,
"quantity"=>1,
"data"=> array(
"id"=> 51,
"post"=>array(
"ID"=>51,
"post_title"=>"Prodcut four - control",
),
"price"=>99
)
),
"a7d0f813832ec8a2bf24269ff7145d0c" => array (
"product" => 6004,
"unique_key" => c30d1ca26d30aa3dc3c9aa04f0b585ce,
"product_id" => 51,
"line_total"=>99,
"quantity"=>1,
"data"=> array(
"id"=> 51,
"post"=>array(
"ID"=>51,
"post_title"=>"Prodcut four - control",
),
"price"=>99
)
)
);
Need to remove the duplicate values based on 'product_id' array value and increase the quantity values based on number of products.
Note: The above array have 'unique key' too so any single unique key is needed in array result.
Expected Result should be:
$resultproduct = array(
"2e471a22b1b994a7cb3f3a40cee9fba2" => array (
"product" => 6004,
"unique_key" => 3a8a5cb029ee3b92cfc90de23e2329ab,
"product_id" => 51,
"line_total"=>99,
"quantity"=>2,
"data"=> array(
"id"=> 51,
"post"=>array(
"ID"=>51,
"post_title"=>"Prodcut four - control",
),
"price"=>99
)
));
Working code at eval.in
I try and make the code easy to understand so more variables and lines of code than is absolutely required.
Explanation:
1) Need to use the one of original product array index as the output table key e.g. "2e471a22b1b994a7cb3f3a40cee9fba2" for product 51.
2) It needs to be fast relating input productId to the output key. So, I used a lookup table ProductIdList that matches productId to output key.
It is then a two stage lookup to find the entry in the output and add quantities to it.
The code:
// create a product_id => first key table
$productIdList = array();
// output...
$productTotal = array();
foreach ($product as $origIndex => $entry) {
$curProductId = $entry['product_id'];
// check product_id exists in the lookup...
if (isset($productIdList[$curProductId])) { // add to the total...
$productTotalIndex = $productIdList[$curProductId];
$productTotal[$productTotalIndex]['quantity'] += $entry['quantity'];
}
else { // add the entry to the output and the productIdList...
$productIdList[$curProductId] = $origIndex;
$productTotal[$origIndex] = $entry;
}
}
Output: The totals array:
Array
(
[2e471a22b1b994a7cb3f3a40cee9fba2] => Array
(
[product] => 6004
[unique_key] => 3a8a5cb029ee3b92cfc90de23e2329ab
[product_id] => 51
[line_total] => 99
[quantity] => 2
[data] => Array
(
[id] => 51
[post] => Array
(
[ID] => 51
[post_title] => Prodcut four - control
)
[price] => 99
)
)
[test02] => Array
(
[product] => 6664
[unique_key] => c30d1ca26d30aa3dc3c9aa04f0b585ce
[product_id] => 666
[line_total] => 99
[quantity] => 579
[data] => Array
(
[id] => 666
[post] => Array
(
[ID] => 666
[post_title] => Prodcut 666 - control
)
[price] => 99
)
)
)
The productId to original key list:
array (size=2)
51 => string '2e471a22b1b994a7cb3f3a40cee9fba2' (length=32)
666 => string 'test02' (length=6)
You need to loop over each product and use the product_id as the key for a new array. This adds the quantities as it goes, so should work for any quantities other than 1.
$result = [];
foreach ($product as $p)
{
if (isset($result[$p['product_id']]))
{
$result[$p['product_id']]['quantity']+= $p['quantity'];
}
else
{
$result[$p['product_id']] = $p;
}
}
print_r($result);

Get the correct loop for/foreach

I have categories with a subcategories. I want to make a links but the subcategories should displayed under category.
Following code/result of my DB:
foreach ($v as $k1 => $v1) {
print_r ($v1); echo ' <br />';
}
Followoing result:
Array ( [head] => 1 [category_id] => 5 [category] => colors [module_id] => 2 )
Array ( [head] => 1 [category_id] => 6 [category] => floors [module_id] => 2 )
Array ( [head] => 5 [category_id] => 7 [category] => wandfarbe [module_id] => 2 )
Array ( [head] => 5 [category_id] => 8 [category] => bodenfarbe [module_id] => 2 )
Array ( [head] => 6 [category_id] => 9 [category] => parkett [module_id] => 2 )
Is it possible to get or to echo the result:
1 | 5
5 | 7
5 | 8
8 | 10
8 | 11
1 | 6
6 | 9
Am I sutpid to do a for loop or foreach loop? Or is it not possible to do subcategory with this array?
Here is a bit of code that can do what you want, it's not too elegant, but it will get the job done.
Basically it will create a nested array where the Category ID is the array key, and Category Id, Name, as well as sub categories ('cats') are values at that level.
In the example below, $hier is the array containing the category hierarchy.
// Check each level of $hier for a key with 'head' value
// if found, add cat id under it, otherwise return false
function findPlace(&$hier, $data)
{
// check for existing position on top level
foreach ($hier as $level => $cats) {
if ($level == $data['head']) {
// the category belongs here
$hier[$level]['cats'][$data['category_id']] = array(
'id' => $data['category_id'],
'name' => $data['category']
);
return true;
}
}
// if not found, check next level down if array
foreach ($hier as $level => $cats) {
if (is_array($cats)) {
return findPlace($hier[$level], $data);
}
}
// did not find a place in hierarchy
return false;
}
// create new entry
function createPlace(&$hier, $data)
{
$hier[$data['head']]['id'] = $data['head'];
$hier[$data['head']]['cats'][$data['category_id']] = array(
'id' => $data['category_id'],
'name' => $data['category']
);
}
Then, since you expressed that you wanted to re-sort using the category name (alphabetically), you can add the following functions to do the sorting:
// case insensitive string compare for alpha sort
function compareNames($a, $b)
{
return strcasecmp($a['name'], $b['name']);
}
// sort array alphabetically by 'name' key
function sortByNameKeys(&$hier) {
foreach ($hier as $key => $sub) {
if (isset($sub['cats']) && !empty($sub['cats'])){
sortByNameKeys($hier[$key]['cats']);
uasort($hier[$key]['cats'], 'compareNames');
}
}
}
Now all you have to do to get your category hierarchy sorted out is loop through your records (categories) and call the findPlace() function, here is an example:
$hier = array(); // category hierarchy will be saved here
foreach ($records as $record) {
findPlace($hier, $record) || createPlace($hier, $record);
}
sortByNameKeys($hier); // re-sort by name, keeping hierarchy
Hope that helps!
Copy/paste this code into a php file, run it and then var_dump the $hier array to get an idea of the structure.

Merge Same Values Array in to One (string value) and sum its corresponding integer value in to same Index?

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);

Categories