PHP output array with identical identifiers - php

I will need to output an array something along the lines of
[
0 => ['text' => 'category'],
1 => ['text' => category']
]
So basicly an array for each category in my database. I need to output them like this because of how they will be exported to another site. (I cannot foreach inside the export)
My current code, is a foreach loop that runs through my categories. If i var_dump my field variable inside the foreach loop i get the result i want, but as mentioned i need to export everything in the format like above out of the foreach loop.
Code:
foreach ($categories as $category) {
$fieldvalue = ['text' => $category->categoryname];
}
What i have tried:
Putting the array in a string to explode outside the loop-
Result: Because of the "same identifier" issue i could only export the last result
What i need to be done:
My current code outputs the array as a text string so basicly
$fieldvalue ? "['text' => '$category->categoryname']";
And my output will be
array:4 [
0 => "['text' => value1]"
1 => "['text' => value2]"
2 => "['text' => value3]"
3 => "['text' => value4]"
]
I just need to get the string to be an array.

Try:
foreach ($categories as $category) {
$fieldvalue[] = ['text' => $category->categoryname];
}
You want the result to be an array that contains many arrays (multi-dimensional array). Using $var[] = $something adds that $something as an array object.

Related

Show images based on String

i want my code to show certain images based on a given string like "Brand1,Brand2,Brand3"
I already declared the images with:
<?php
$brandString ="Brand1,Brand2,Brand3";
$images = [
'Brand1' => 'Brand1.png',
'Brand2' => 'Brand2.png',
'Brand3' => 'Brand3.png',
'Brand4' => 'Brand4.png'
];
Now I only want to show the images that are declared in the string. What is the best way to do this?
Using explode, you can split the string into an array on every occurance of a comma. That way you can just run through your brand array by using foreach.
So, using your example it would look something like this:
<?php
$brandString ="Brand1,Brand2,Brand3";
$brandArray = explode(",", $brandString);
$images = [
'Brand1' => 'Brand1.png',
'Brand2' => 'Brand2.png',
'Brand3' => 'Brand3.png',
'Brand4' => 'Brand4.png'
];
foreach($brandArray AS $brand) {
echo $images[$brand]; //this would print out the image names in order: Brand1.jpg, Brand2.jpg, Brand3.jpg
}

Adding new data to this array

I have an array that has been filled with default data as shown below
$arrivals = array(
"source" => "arrivals",
"data" => array(
0 => array("flight"=>"000","scheduled"=>"0000","city"=>"Geneva","airline"=>"UAL","gate"=>"A00","status"=>"1","remarks"=>"BOARDING"),
1 => array("flight"=>rand(1,2000),"scheduled"=>randomTime(),"city"=>"Baltimore","airline"=>randomAirline(),"gate"=>"A7","status"=>"0","remarks"=>"")
)
);
Now i want to create the same array with data from a table in a loop using the same identifiers such as 'city' but with variable names .
The other part is that the first part of 'data' array is a number which of course in a loop I can use a counter.
The problem is that the Array is created with the static value of ""source" => "arrivals" for which there is only one value for the array and then the arrays of 'data'.
I would like an easy way to set up an array dynamically with a number of records but with the one header of ""source" => "arrivals" and multiple entries for "data' i.e. one element per record I fetch from my table
Thank you
You can do this with a foreach loop in php after you have retrieved your data.
// Get the data from your table source
$data = get_some_data();
$arrivals = [
'source' => 'arrivals',
'data' => []
];
foreach ($data as $city) {
$arrivals['data'][] = [
'flight' => $city['flight'],
'scheduled'=> $city['scheduled'],
'city' => $city['city'],
// etc.
];
}
Alternatively, if you would like to assign the city name as the array key in arrivals, you can replace the first line inside the foreach loop with $arrivals['data'][$city['city']] (or whatever array item holds the city value).

Cakephp 3 query with conditions array build in foreach loop

Hello i want to use an array as condition.
For example i have services with a zip as combination
12345 => cleaning,
54321 => cleaning
now i build my array together in a foreach loop
$searcharray = [];
foreach($services as $key => $val){
searcharray[] = array('service' => $val['service'], 'zip' => $val['zip']);
}
My search array lookes like this:
[
(int) 0 => [
'service' => 'cleaning',
'zip' => '12345'
],
(int) 1 => [
'service' => 'cleaning',
'zip' => '54321'
]
]
Then i try to get the data from my request table
$this->loadModel('Requests');
$openrequests = $this->Requests->find('all', array(
'conditions' => array(
'OR' => array(
$searcharray
)
)
));
It didnt work maybe of the keys in the array, because i set after the $searcharray for example [1] and then it works. I dont want to write the condition as string, but how can i solve it?
You have nested the conditions one level too deep.
Your $searcharray is already nested correctly, if you nest it again as in your example, then you're basically creating an OR node with only one child (which in turn has children itself), which is interpreted as basically "nothing", as you need at least two children for an operator to be used. The children in the array nested one level deeper will then be interpreted as AND, as that is the default when no operator is specified.
Long story short, just pass $searcharray as is:
'conditions' => [
'OR' => $searcharray,
]
See also
Cookbook > Database Access & ORM > Query Builder > Advanced Conditions

how to process my array to be associative on first two levels and on third to have simple value

I'm trying to construct an array where there only strings and the array would look like this
key->key->value
To explain it I attached two screenshots below.
I start with this:
After my code below I'm 90% there, yet there is an array in value on the third level instead of simple value.
Here is some code:
$theme = ThemeHandler::with('sections.settings')->find($activeTheme);
$themeSettings = $theme->sections;
$themeSettings = collect($themeSettings->toArray());
// dd($themeSettings);
$themeSections = [];
foreach ($themeSettings as $key => $value) {
$settings = collect($value['settings']);
$settings = $settings->mapToGroups(function ($item) {
return [$item['key'] => $item['value']];
});
$themeSections[$value['key']] = $settings->toArray();
}
dd($themeSections);
I would like to end up with this structure
key->key->value
and not
key->key->single_element_array->value
I'm not sure how I end up with an array at the bottom level when I do this
return [$item['key'] => $item['value']];
inside the mapToGroups, which is a function found here: https://laravel.com/docs/5.8/collections#method-maptogroups
Maybe I misunderstand how mapToGroups work. Anybody has an idea how to get key->key->value structure output?
Use mapWithKeys() instead of mapToGroups().
You're getting an array instead of the simple value you expect because the value is a group, albeit a group with only one member.
mapToGroups() groups all the values with the same key, but mapWithKeys() will assign a single value to each key.
You can see in the examples in the collection documentation, mapToGroups() produces a result like this:
[
'Sales' => ['John Doe', 'Jane Doe'],
'Marketing' => ['Johnny Doe'],
]
And mapWithKeys() result is like this:
[
'john#example.com' => 'John',
'jane#example.com' => 'Jane',
]

Multidimensional array loop with array search

I realize there are a number of questions about multidimensional arrays and foreach loops, and I have spent hours reading through them and trying to get my own loop to work -- without success. If the solution is a duplicate, I'll remove my question (or link to another if that is preferred).
Now, the challenge:
Using an array of returned MYSQL results. The results are from multiple joined tables in an associative array. Now I need to convert it to the multidimensional array I need.
I've got most of it working, but my issue is looping through and adding new items to the right place in the array.
Here's some code:
//example of how array is setup in the way I want, this part works.
foreach($results as $i => $a):
//some other code is here, see below.
$items[$i] = [
"id" => $a['id'],
"itemid" => $a['itemid'],
"name" => $a['name'],
"def" => $a['def'],
"class" => $a['class'],
"timeline" => $a['timeline'],
"files" => [
[0] => [
"id" => $a['fileid'],
"name" => $a['filename'],
"path" => $a['filepath'],
"type" => $a['filetype']
]
],
"tags" => [
[0] => [
"id" => $a['tagid'],
"name" => $a['tagname']
]
]
];
endforeach;
Then I've tried a number of ways to loop through in order to only add to the 'tags' or 'files' if the item 'id' is the same as the last. Here is the current code in my editor, not working:
//inside foreach loop, before above code
if($items[$i-1]['id'] == $a['id']):
//it is the same item, works to here.
if(in_array($a['filename'], $items[$i-1], FALSE)):
//add to files array for last item
$items[$i-1]['files'][] = [
"id" => $a['fileid'],
"name" => $a['filename'],
"path" => $a['filepath'],
"type" => $a['filetype']
];
elseif(in_array($a['tagname'], $items[$i-1], FALSE)):
//add to tags array for last item
$items[$i-1]['tags'][] = [
"id" => $a['tagid'],
"name" => $a['tagname']
];
endif;
else:// else it does the code above
As you can see, my most recent attempt was to use in_array, which I now realize doesn't work on multidimensional arrays. My issue is that I can't figure out how to determine if its a new file or new tag for the same item.
Ultimately, I want an array of 'items' which have multiple 'files' and 'tags.' I'm going to json_encode and use it with JS afterwards.
Any advice on how to get this working or optimize it, would be greatly appreciated.
P.S. As I mentioned above, I know this question has been asked before -- though I wasn't able to get their solutions working for me. I'll remove this question if the solution is a duplicate (as in, it's not really helpful to others). Thank you for any help, it is greatly appreciated!
Don't use "autoincrementing" array indices as they easily get messed up. Use your database id since it's already there:
//example of how array is setup in the way I want, this part works.
foreach($results as $i => $a):
$items[$a['id']] = [ // THIS CHANGED.
"id" => $a['id'],
"itemid" => $a['itemid'],
...
Now, with any further result, you can easily check, if the id is already in your array:
if (isset($items[$a['id']])) {
// We had this id before, just add files/tags to it.
// Check first, if files subarray exists, if not: create it.
if (!isset($items[$a['id']]['files'])) {
$items[$a['id']]['files'] = array();
}
$items[$a['id']]['files'][] = array(...); // add the new file.
// Repeat for tags.
}
If your result could return the same file more than once for an id, you can check if the filename is already in there by using a search function:
$filename = $a['filename'];
if (!searchFilename($filename, $items[$a['id']]['files']) {
// Filename is not in there, yet.
// Add file info.
}
function searchFilename($id, $array) {
foreach ($array as $key => $val) {
if ($val['filename'] === $id) {
return true;
}
}
return false;
}
Same applies to tags in a similar way.
In the end, if you do not want the ids for index of $items, just call:
$items = array_values($items);

Categories