array_splice with multidimensional array breaks inserted array - php

I have the following array structure:
$tpl = [
'breadcrumbs' => [
[ 'title' => 'Item Database', 'text' => 'Item Database', 'url' => SITE_DOMAIN.ADMIN_PATH.'/items/' ],
[ 'title' => $category->name, 'text' => $category->name, 'active' => true ]
]
];
I am attempting to insert an element before the last element, so thought I could use array_splice as follows:
if( !is_null($category->category) )
{
array_splice(
$tpl['breadcrumbs'],
1,
0,
[ 'title' => $category->category->name, 'text' => $category->category->name, 'url' => SITE_DOMAIN.ADMIN_PATH.'/items/' ]
);
}
However, this seems to flatten the item I am trying to insert (as per the expected behaviour) and produces the following output:
Array
(
[0] => Array
(
[title] => Item Database
[text] => Item Database
[url] => https://local/qmdepot/admin/items/
)
[1] => Medical Department
[2] => Medical Department
[3] => https://local/qmdepot/admin/items/
[4] => Array
(
[title] => Class 1
[text] => Class 1
[active] => 1
)
)
While the expected output should be:
Array
(
[0] => Array
(
[title] => Item Database
[text] => Item Database
[url] => https://local/qmdepot/admin/items/
)
[1] => Array
(
[title] => Medical Department
[text] => Medical Department
[url] => https://local/qmdepot/admin/items/
)
[2] => Array
(
[title] => Class 1
[text] => Class 1
[active] => 1
)
)
I am able to achieve this using the following code, but it feels a little hacky to me:
# Set up the breadcrumbs:
if( !is_null($category->category) )
{
$tpl['breadcrumbs'][2] = $tpl['breadcrumbs'][1];
$tpl['breadcrumbs'][1] = [ 'title' => $category->category->name, 'text' => $category->category->name, 'url' => SITE_DOMAIN.ADMIN_PATH.'/items/' ];
}
Is there any way to insert an array item into a multi-dimensional array at a specified index without writing a custom function or using the hack above?

Since the item you want to insert is an array, and array_splice takes an array of items, put your array in an array.
Also since you want to insert something before the last element you can use a negative number for the offset to count backward from the end. (The effect is the same with the data you've got, but matters on arrays of different sizes.)
array_splice(
$tpl['breadcrumbs'],
-1,
0,
[[ 'title' => $category->category->name, 'text' => $category->category->name, 'url' => SITE_DOMAIN.ADMIN_PATH.'/items/' ]]
);

Related

Count Total Indexes of Array in PHP

I have an array with the following structure:
Array
(
[DigitalAssets] => Array
(
[0] => Array
(
[PartNumber] => 0276S-4
[Link] => https://1ddf4b1b856a39e33863-d785dc0e3b62b5e0ef07f55db00b0659.ssl.cf2.rackcdn.com/Holley/0576s-4.jpg
[AssetTypeCode] => P04
[FileName] => 0576s-4.jpg
[RecordModifiedDate] => 2020-05-13T18:59:10.28
)
[1] => Array
(
[PartNumber] => 0437S-4
[Link] => https://1ddf4b1b856a39e33863-d785dc0e3b62b5e0ef07f55db00b0659.ssl.cf2.rackcdn.com/Holley/0437s-4.jpg
[AssetTypeCode] => P04
[FileName] => 0437s-4.jpg
[RecordModifiedDate] => 2020-05-13T18:59:11.687
)
[2] => Array
(
[PartNumber] => 0574S-4
[Link] => https://1ddf4b1b856a39e33863-d785dc0e3b62b5e0ef07f55db00b0659.ssl.cf2.rackcdn.com/Holley/0574s-4.jpg
[AssetTypeCode] => P04
[FileName] => 0574s-4.jpg
[RecordModifiedDate] => 2020-05-13T18:59:12.593
)
I want to count the total Indexes of array so that I will run loop accordingly. I used Count($array) and Count ($array,RECURSIVE) but it cannot return the correct total number of indexes.
Can only guide that how to do this?
Thanks
If You want to count DigitalAssets direct children You can do this
count($array['DigitalAssets'])
Here are some tests how count should work.
Code is:
$test = array
(
'DigitalAssets' => array
(
0 => array(
'PartNumber' => '0276S-4',
'Link' => 'https://1ddf4b1b856a39e33863-d785dc0e3b62b5e0ef07f55db00b0659.ssl.cf2.rackcdn.com/Holley/0576s-4.jpg',
'AssetTypeCode' => 'P04',
'FileName' => '0576s-4.jpg',
'RecordModifiedDate' => '2020-05-13T18:59:10.28'
),
1 => array(
'PartNumber' => '0437S-4',
'Link' => 'https://1ddf4b1b856a39e33863-d785dc0e3b62b5e0ef07f55db00b0659.ssl.cf2.rackcdn.com/Holley/0437s-4.jpg',
'AssetTypeCode' => 'P04',
'FileName' => '0437s-4.jpg',
'RecordModifiedDate' => '2020-05-13T18:59:11.687'
),
2 => array
(
'PartNumber' => '0574S-4',
'Link' => 'https://1ddf4b1b856a39e33863-d785dc0e3b62b5e0ef07f55db00b0659.ssl.cf2.rackcdn.com/Holley/0574s-4.jpg',
'AssetTypeCode' => 'P04',
'FileName' => '0574s-4.jpg',
'RecordModifiedDate' => '2020-05-13T18:59:12.593'
)
)
);
echo count($test['DigitalAssets'])." ".count($test['DigitalAssets'], 0)." ".count($test['DigitalAssets'], 1);
exit();
Result in my case:
3 3 18
This means taht in my case mode in count is set to 0 by default so i will get only first level counted. If i set mode to 1 i will get all nested items counted as well. This should clear things up for You.

Remove duplicate combination of elements from multidimensional array

I have an array with fields:
$products = array(
[0] => array('name' => 'product_one', 'category' => 'category_one', employee => '3234'),
[1] => array('name' => 'product_two', 'category' => 'category_two', employee => '5421'),
[2] => array('name' => 'product_three', 'category' => 'category_one', employee => '3234'),
[3] => array('name' => 'product_one', 'category' => 'category_one', employee => '2153'),
[4] => array('name' => 'product_one', 'category' => 'category_two', employee => '6312')
)
Now, in this case, employee field is not important, but the combination of product/category is unique.
Wanted result:
$products = array(
[0] => array('name' => 'product_one', 'category' => 'category_one', employee => '3234'),
[1] => array('name' => 'product_two', 'category' => 'category_two', employee => '5421'),
[2] => array('name' => 'product_three', 'category' => 'category_one', employee => '3234'),
[4] => array('name' => 'product_one', 'category' => 'category_two', employee => '6312')
)
Any idea what is the best way to do this? On production, I have more than 30.000 elements and usually around 10 duplicates. Also in real database, I have 12 fields and a combination of 4 of them needs to be unique).
If you don't mind which of the duplicates you keep, it's probably simplest to iterate over the loop, making a new array with keys which are a combination of the required unique values (I've used a separator of ## in this code, you can use anything that cannot occur in the values). This way duplicates will be automatically removed as an array cannot have identical keys. Once the loop is done the output array can be re-indexed numerically using array_values:
$output = array();
foreach ($products as $p) {
$output["{$p['name']}##{$p['category']}"] = $p;
}
$output = array_values($output);
print_r($output);
Output (for your sample data):
Array
(
[0] => Array
(
[name] => product_one
[category] => category_one
[employee] => 2153
)
[1] => Array
(
[name] => product_two
[category] => category_two
[employee] => 5421
)
[2] => Array
(
[name] => product_three
[category] => category_one
[employee] => 3234
)
[3] => Array
(
[name] => product_one
[category] => category_two
[employee] => 6312
)
)
Demo on 3v4l.org

how to pass the array to gridview in yii2

im using yii2 framework
I have array coming from controller to the view.
public function actionProducts()
{
$product = Yii::$app->httpclient->get('http://localhost/MWSProducts/src/MarketplaceWebServiceProducts/Samples/GetMatchingProductSample.php');
$array1 = str_replace("ns2:","",$product);
$array=json_decode(json_encode(simplexml_load_string($array1)),true);
return $this->render('products',['array'=>$array]);
}
In the above code im converting xml to an array.
The $array has the array, and im passing it to view called products. Now i want to display that array in the view in Gridview, Since im new to yii2 im unable to do this, it says i have to use some dataprovider, but im not getting how to do this.
Can anyone please help me in this how do i display the array in gridview. Thank you
Thanks for the answer..
Actually its a amazon product array im fetching it from the Product API, we cant define any predefine attributes like id and all, since its different for each product. this is how the array looks like.
Array
(
[GetMatchingProductResult] => Array
(
[0] => Array
(
[#attributes] => Array
(
[ASIN] => 0886467918
[status] => Success
)
[Product] => Array
(
[Identifiers] => Array
(
[MarketplaceASIN] => Array
(
[MarketplaceId] => A21TJRUUN4KGV
[ASIN] => 0886467918
)
)
[AttributeSets] => Array
(
[ItemAttributes] => Array
(
[Author] => Kipling, Rudyard
[Binding] => Hardcover
[Edition] => Har/Cas
[Format] => Import
[Label] => Imprint unknown
[Languages] => Array
(
[Language] => Array
(
[0] => Array
(
[Name] => english
[Type] => Published
)
[1] => Array
(
[Name] => english
[Type] => Original Language
)
[2] => Array
(
[Name] => english
[Type] => Unknown
)
)
)
[Manufacturer] => Imprint unknown
[PackageDimensions] => Array
(
[Weight] => 1.74
)
[ProductGroup] => Book
[ProductTypeName] => ABIS_BOOK
[PublicationDate] => 1988-05-02
[Publisher] => Imprint unknown
[SmallImage] => Array
(
[URL] => http://ecx.images-amazon.com/images/I/412CsE6Mb8L._SL75_.jpg
[Height] => 75
[Width] => 50
)
[Studio] => Imprint unknown
[Title] => Jungle Book ("Read Along")
)
)
[Relationships] => Array
(
)
[SalesRankings] => Array
(
[SalesRank] => Array
(
[0] => Array
(
[ProductCategoryId] => book_display_on_website
[Rank] => 709468
)
[1] => Array
(
[ProductCategoryId] => 1318084031
[Rank] => 14260
)
[2] => Array
(
[ProductCategoryId] => 1318083031
[Rank] => 47016
)
)
)
)
)
If the array contain the data like a dataProvider . you can use arrayDataProvider http://www.yiiframework.com/doc-2.0/yii-data-arraydataprovider.html eg (from yii2 guide):
$data = [
['id' => 1, 'name' => 'name 1', ...],
['id' => 2, 'name' => 'name 2', ...],
...
['id' => 100, 'name' => 'name 100', ...],
];
$provider = new ArrayDataProvider([
'allModels' => $data,
'pagination' => [
'pageSize' => 10,
],
'sort' => [
'attributes' => ['id', 'name'],
],
]);
a brief guide to dataprovider http://www.yiiframework.com/doc-2.0/guide-output-data-providers.html
in your case
public function actionProducts()
{
$product = Yii::$app->httpclient->get('http://localhost/MWSProducts/src/MarketplaceWebServiceProducts/Samples/GetMatchingProductSample.php');
$array1 = str_replace("ns2:","",$product);
$array=json_decode(json_encode(simplexml_load_string($array1)),true);
$provider = new ArrayDataProvider([
'allModels' => $array,
'pagination' => [
'pageSize' => 10,
],
]);
return $this->render('products',['array'=>$array]);
}
Refer to sample above where the array $data contain id, name and suppose your arrayDataProvider is in the var $array and have id,name too in gridview you should have
<?= GridView::widget([
'dataProvider' => $array,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'name',
.....
['class' => 'yii\grid\ActionColumn',
'contentOptions' => ['style' => 'width:84px; font-size:18px;']],
],
]); ?>

How to append value to all subarrays in PHP without a loop? [duplicate]

This question already has answers here:
PHP Add element to every sub array of multi dimension array
(3 answers)
Closed 2 years ago.
I have the following array:
Array (
[0] => Array (
'id' => ...
'name' ...
),
[1] => Array (
'id' => ...
'name' ...
),
[2] => Array (
'id' => ...
'name' ...
),
[3] => Array (
'id' => ...
'name' ...
),
)
What I want to do is to append the same pid key-value pair to every subarray. Is there an easy way to do this without having to do a foreach?
without having to explicitly use a foreach or some other kind of loop, you can use PHP's array_map function. although this will perform an iterated loop under the hood, it will return an array with each element processed by your function.
<?php
$arr = Array (
0 => Array (
'id' => 1,
'name' => 'one'
),
1 => Array (
'id' => 2,
'name' => 'two'
),
2 => Array (
'id' => 3,
'name' => 'three'
),
3 => Array (
'id' => 4,
'name' => 'four'
)
);
function append_pid_kvpair($n){
$n ['pid']= 'value';
return $n;
}
$arr = array_map("append_pid_kvpair",$arr);
echo "<pre>".print_r($arr,true)."</pre>";
will result in this output
Array
(
[0] => Array
(
[id] => 1
[name] => one
[pid] => value
)
[1] => Array
(
[id] => 2
[name] => two
[pid] => value
)
[2] => Array
(
[id] => 3
[name] => three
[pid] => value
)
[3] => Array
(
[id] => 4
[name] => four
[pid] => value
)
)

codeigniter insert multi-dimensional array to the database

Hello I have this multi dimensional array which needs to be inserted to the database table.
so far I have come up with this solution which don't work fully. I have a form that support dynamic fields many dynamic fields. I want to save those dynamically created fields using this function. First I had been able to create a loop to format the data.
I used this loop to format the data
$url = str_replace(' ','-',strtolower($this->input->post('title')));
$data = ['business' => [
'title' => $this->input->post('title'),
'URL' => $url,
'category' => $this->input->post('category'),
'region' => $this->input->post('region')
],
'description_' => [
'text' => $this->input->post('description'),
],
'logo_' => [
'blob' => $this->input->post('logo'),
]];
$nyingi = [ 'location_' => ['text' => 'loc_txt','priority' => 'loc_order'],
'photo_' => ['path' => 'p_txt'],
'video_' => ['path' => 'v_txt'],
'product_' => ['p_id' => 'pt_q', 'text' => 'pt_txt', 'expire' => 'pt_xpr', 'title' => 'pt_tt'],
'service_' => ['p_id' => 'st_q', 'text' => 'st_txt', 'expire' => 'st_xpr', 'title' => 'st_tt'],
'hours_' => ['time1' => 't1', 'time2' => 't2', 'type' => 'tt'],
'map_' => ['text' => 'm_txt']
];
foreach($nyingi as $ins => $vl){
foreach($vl as $fld => $box){
$uwazi = $this->input->post($box);
if(is_array($uwazi) && 1<count($uwazi)){
foreach($uwazi as $bb){
$one[$ins][$fld][] = $bb;
}
} elseif(is_array($uwazi) && 1==count($uwazi)) {
print_r($uwazi);
}
}
}
for($g=0;$g<count($one);$g++){
for($h=0;$h<count($one[$g]);$h++){
for($z=0;$z<count($one[$g][$h]);$z++){
//if(array_key_exists($one[$g][$h+1], $one)){
print $one[$g][$h][$z+1];
//}
}
}
}
$data = array_merge($data, $one);
The output of the above code
[location_] => Array
(
[text] => Array
(
[0] => Lemara Main Office
[1] => Themi branch
[2] => Sinoni branch
)
[priority] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
)
[photo_] => Array
(
[path] => Array
(
[0] => lemaraphoto.png
[1] => themiphoto.png
[2] => sinoniphoto.png
)
)
[video_] => Array
(
[path] => Array
(
[0] => lemaravideo.mp4
[1] => themivideo.mp4
[2] => sinonivideo.mp4
)
)
[product_] => Array
(
[p_id] => Array
(
[0] => product photo
[1] => product 3 photo
[2] => Product 2 photo
)
[text] => Array
(
[0] => product desc
[1] => product 3 desc
[2] => product 2 desc
)
[expire] => Array
(
[0] => product expire
[1] => product 3 expire
[2] => Product 2 expire
)
[title] => Array
(
[0] => product
[1] => Product 3
[2] => Product 2
)
)
[service_] => Array
(
[p_id] => Array
(
[0] => Service 2 photo
[1] => service 3 photo
[2] => service photo
)
[text] => Array
(
[0] => service 2 desc
[1] => service 3 desc
[2] => service desc
)
[expire] => Array
(
[0] => Service 2 expire
[1] => service 3 expire
[2] => service expire
)
[title] => Array
(
[0] => Service 2
[1] => service 3
[2] => service
)
)
)
I have this add_bz function
function add_bz($data){
$this->db->trans_start(); $er=0;
foreach($data as $table => $sql){
if($table==="business"){
$this->db->insert($table, $sql);
$id = $this->db->insert_id();
} else {
array_merge($sql, array('idd' => $id));
$this->db->insert($table, $sql);}
}
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE){print "Transaction Fails";return FALSE;}
return TRUE;
}
That function allows me to insert the data in this format only.
[[business] => Array
(
[title] => Email Marketing
[URL] => email-marketing
[category] => 3
[region] => 2
)
[description_] => Array
(
[text] => Some desc
)
[logo_] => Array
(
[blob] => mainlogo.png
)
]
as business, decription_, logo_ are db tables where title, URL, category, region, text, blob are the db columns to the corresponding tables and the rest is data that goes to those columns.
How I want it to works. For example in location_
I want to the array to change into my working format or something else that will work like this
location_ => ['text' => [[0] => 'Lemara Main Office'],
'priority' => [[0] => '1']
]
location_ => ['text' => [[1] => 'Themi Office'],
'priority' => [[1] => '2']
]
location_ => ['text' => [[2] => 'Sinoni Office'],
'priority' => [[2] => '3']
]
or like this
location_ => [0 => [['text' => 'Lemara Main Office'],
['priority' => '1']
],
1 => [['text' => 'Themi Main Office'],
['priority' => '2']
],
2 => [['text' => 'Sinoni Main Office'],
['priority' => '3']
]
],
And also support many columns not just the two.
Any help is deeply appreciated as I have been struggling for days to make this work. Thanks in advance.
I would suggest you convert your array to JSON String then insert it to DB as text.
JSON would handle your multidimentional data so well,
To convert your array to JSON : http://php.net/manual/en/function.json-encode.php
To convert your JSON to Array : http://php.net/manual/en/function.json-decode.php

Categories