Send associative array from a multiple select - php

I need to send an associative array from a multiple select.
I have this code:
<select name="frontend_footer_menu_pages[]" id="frontend_footer_menu_pages" class="form-control" multiple>
<?php foreach($pages as $page): ?>
<option value="<?php echo $page->url; ?>">
<?php echo $page->page; ?>
</option>
<?php endforeach; ?>
And this is producing:
Array(
[0] => first/page,
[1] => second/page
)
I need to obtain something like this:
Array(
['first/page'] => 'First Page',
['second/page'] => 'Second Page']
);
I am not able to produce name/value in associative way and not in numeric way because I can't retrieve the content of option ($page->page)
Thank you in advance
G

When the form is submitted you will indeed get something like this array in PHP:
Array(
[0] => first/page,
[1] => second/page
)
This is how it works, and I would not suggest to try to change this behaviour. However, you can convert this to the associative array of your liking.
First create an associative array for your pages, so you can quickly find the page name for a given url:
// Create hash for the pages, keyed by their page name:
foreach ($pages as $page) {
$pageHash[$page->page] = $page->url;
}
You already have your submitted list of selected items. Your existing code will have something like this:
$selected = $_POST['frontend_footer_menu_pages'];
Now, to convert this to the associative array you are looking for, just use array_intersect with the hash we created above, and then swap keys and values with array_flip:
$selected = array_flip(array_intersect($pageHash, $selected));
The outcome will be something like this:
Array
(
[first/page] => First Page
[second/page] => Second Page
)

Related

PHP getting a specific key value at a specfic index in an array

I've looked a bunch on here, and I've seem some similar type of questions, but none of them seemed to work in my situation (or at least I couldn't make them work), so hopefully this isn't an exact repeat.
I built an array that looks as follows:
Array
(
[0] => Array
(
[article_id] => 1
[article_title] => Article 1
[article_content] => This is some dummy text for the first article.
)
[1] => Array
(
[article_id] => 2
[article_title] => Article 2
[article_content] => This is the content for article #2
)
)
So the array has 3 keys (article_id, article_title, article_content), and what I'm trying to do is get a specific value at a specific index.
So, for example, if the page url is
/article.php?id=1
I first assign the id to a variable:
$linkID = $_GET['id'];
and now I want to search the array to find an article id match (to the $LinkID variable):
$foundAtPos = array_search($linkID, array_column($datas, 'article_id'));
this works fine, and gives me a matching "index" position, which is a great start, and now I want to assign the other two key values to variables (or echo them to the screen, something to show me that I've retrieved the correct id - article_title value).
This is the part where I get really stuck. I can easily display all values from the array, but I'm not looking to do that. I want to get ONLY the specific values that match the corresponding article_id.
Here's a few things I've tried (unsuccessfully):
foreach ($datas as $keyName) {
echo $keyName['article_title'];
}
This gives me all the article titles, but that's not what I'm aiming for.
This bit I got from another stack overflow post, and it seemed like it was close, but I couldn't adapt it correctly.
foreach($datas as $firstKey => $firstValue) {
echo array_keys($firstValue, $firstValue['article_title'])[0].': '.$firstValue['article_title'].'</br>';
}
Same problem, gives me all the data, not just the row I'm trying to retrieve.
So I've gone in circles for hours, and it seems like this should be a common thing, but it's eluding me at the moment, so I'd appreciate any suggestions you fine folks might have.
Here's my entire function, for reference.
if (isset($_GET['id'])) {
$linkID = $_GET['id'];
foreach ($datas as $keyName) {
//echo $keyName['article_title'];
}
//foreach($datas as $firstKey => $firstValue) {
//echo array_keys($firstValue, $firstValue['article_title'])[0].': '.$firstValue['article_title'].'</br>';
//}
//retrieve index of match in array
$foundAtPos = array_search($linkID, array_column($datas, 'article_id'));
print_r($datas[$foundAtPos]);
} else {
header('Location: index.php');
exit();
}
thanks!
You can simplify this a lot by just using array_column with null as the $column_key argument.
This will re-index the entire array with the article_id.
Array
(
[1] => Array
(
[article_id] => 1
[article_title] => Article 1
[article_content] => This is some dummy text for the first article.
)
[2] => Array
(
[article_id] => 2
[article_title] => Article 2
[article_content] => This is the content for article #2
)
)
Then you can use isset on the $linkID of the resulting array.
Example: https://3v4l.org/Fmj9K
if (isset($_GET['id'])) {
$linkID = $_GET['id'];
$articles = array_column($datas, null, 'article_id');
if (isset($articles[$linkID])) {
$article = $articles[$linkID];
//optionally convert from an array values to variable values.
$article_title = $article['article_title'];
$article_content = $article['article_content'];
}
}
Or in PHP 7.1+ you can use list with the key names
Example: https://3v4l.org/C2c4K
if (isset($_GET['id'])) {
$linkID = $_GET['id'];
$articles = array_column($datas, null, 'article_id');
if (isset($articles[$linkID])) {
list('article_title' => $title, 'article_content' => $content) = $articles[$linkID];
}
}
If you already know the ID then just loop on that sub-array:
$foundAtPos = array_search($linkID, array_column($datas, 'article_id'));
foreach ($datas[$foundAtPos] as $key => $value) {
echo $key . ': '. $value;
}
or if you want to get a specific key/value pair at some index then you can use the bracket operator:
$foundAtPos = array_search($linkID, array_column($datas, 'article_id'));
echo $datas[$foundAtPos]['article_title'];

Foreach data list from array - incrementing numbers

I am trying to create a option list from a JSON decoded API link.
So far I have the access to the API sorted, all the data I need stored in a single variable and can extract data from the variable using
print_r($result[0]["ORGANISATION_NAME"]);
print_r($result[1]["ORGANISATION_NAME"]);
This will give me two different Organisation names from the array.
What I would like to do is put this in an alphabetical drop down menu, but for some reason I cannot for the life of me get foreach to work. All we need to do is increment the 0,1,2,3 etc to the number of records stored in the database.
I have no idea on how to do that !
To answer your question as asked:
foreach ($results as $result) {
for ($i = 0; $i < count($result); $i++) {
print_r($result[$i]["ORGANISATION_NAME"]);
}
}
However, why not just another foreach?
EDIT:
Updating based off of new info:
Assuming $result is your DB result here is your new code:
foreach ($result as $row) {
print_r($row['ORGANISATION_NAME']);
}
I think a couple of sensible steps of data preparation will help to simplify this task for you.
Isolate the desired column of data and create a new 1-dimensional array of organization names.
Sort the names alphabetically.
Then you can use a simple foreach loop to generate the html select field.
Code (Demo)
$result = [
["ORGANISATION_NAME" => "B Name"],
["ORGANISATION_NAME" => "D Name"],
["ORGANISATION_NAME" => "C Name"],
["ORGANISATION_NAME" => "A Name"]
];
echo "Proof of correct structure: {$result[1]["ORGANISATION_NAME"]}\n";
$org_names = array_column($result, "ORGANISATION_NAME");
sort($org_names);
var_export($org_names); // display alphabetized array
echo "\n---\n";
echo "<select name=\"orgs\">";
foreach ($org_names as $org) {
echo "<option>$org</option>";
}
echo "</select>";
Output:
Proof of correct structure: D Name
array (
0 => 'A Name',
1 => 'B Name',
2 => 'C Name',
3 => 'D Name',
)
---
<select name="orgs">
<option>A Name</option>
<option>B Name</option>
<option>C Name</option>
<option>D Name</option>
</select>

Add certain results in a foreach to a shared container element

I'm struggling to verbalise this question, but hopefully I can demonstrate it:
I wish for certain results in a foreach loop to be grouped together in a container in the front-end.
So, if, for example, I have a foreach loop running through an array of car names and colours:
foreach($cars as $car){
echo '<h1>'.$car->name.'</h1>';
echo '<p>'.$car->colour.'</p><br/>';
}
It may give me:
<h1>Car1</h1>
<p>Blue</p><br/>
<h1>Car2</h1>
<p>Blue</p><br/>
<h1>Car3</h1>
<p>Red</p><br/>
However I need to group results with the same colour into a container div, so the output looks like:
<div class="blue">
<h1>Car1</h1>
<p>Blue</p><br/>
<h1>Car2</h1>
<p>Blue</p><br/>
</div>
<h1>Car3</h1>
<p>Red</p><br/>
Because the container div is technically outside of each loop I'm not sure how I can get it in there without using front-end script (i.e. javascript), but I'm hoping there's a way… any ideas? Perhaps even a way to identify the first of a type and the last of a type - but that's the closest I can get to a theory, let a lone a solution.
Edit: It appears there was some misunderstanding over the question. I wasn't looking to programatically group within the foreach, simply 'wrap' pre-grouped items.
Use a multi-dimensional array to build your data structure, then loop through the array to display your output.
Something like this:
$mycars = array();
foreach($cars as $car){
$mycars[$car->colour][] = $car;
}
Now you have an array that looks like this:
Array
(
[Blue] => Array
(
[0] => {Car1Object}
[1] => {Car2Object}
)
[Red] => Array
(
[0] => {Car3Object}
)
)
Now loop through that array to display your output:
foreach($mycars as $colour => $cars) {
echo "<div class='$colour'>";
foreach($cars as $car) {
echo "<h1>{$car->name}</h1>";
echo "<p>{$car->colour}</p>";
}
echo "</div>";
}
And you get...
<div class='Blue'>
<h1>Car1</h1>
<p>Blue</p>
<h1>Car2</h1>
<p>Blue</p>
</div>
<div class='Red'>
<h1>Car3</h1>
<p>Red</p>
</div>

Breaking a MultiDimensional Array into a Single Dimension

I have fields in mySQL which is currently being stored like this under the field "tags"
Shopping|Health & Beauty
Coffee|Shopping
What I'm trying to do is to loop through this to create a single dimension array and to grab only the unique values.
I have my query selecting DISTINCT tags from TABLE and run the loop like this:
while ($row_tags = mysql_fetch_assoc($r_tags)) {
$tags = $row_tags['tags'];
$imploded_tags[] = explode("|",$tags);
}
echo "<pre>";
print_r($imploded_tags);
The result from the print_r is showing it as a multidimensional array. I've tried to reexplode it and implode it in different ways, but I haven't been able to get any success. Is there a way that I can create this into a single dimension array? Not all tags will have an equal amount of tags separated by |, so I can't seem to get it to go with a function that I tried from another StackOverflow post. Any help would be greatly appreciated!
OUTPUT:
Array
(
[0] => Array
(
[0] => Shopping
[1] => Health & Beauty
)
[1] => Array
(
[0] => Coffee
[1] => Shopping
)
try this
while ($row_tags = mysql_fetch_assoc($r_tags)) {
$tags = $row_tags['tags'];
$tags = explode("|",$tags);
foreach($tags as $v){
$imploded_tags[] = $v;
}
}
I would do something like:
$imploded_tags = array_merge(explode("|",$tags), $imploded_tags);
}
$imploded_tags = array_unique($imploded_tags);
echo "<pre>";
print_r($imploded_tags);
See the manual on array_merge and array_unique.
However, I do think you are not using the right way to store your tags; they should be stored in a separate table as separate values.
What's going on is when you're fetching your rows from MySQL, you're essentially getting a bunch of data in an array in the first place, which is why you have to loop through them.
With your your implode function, you're taking a bunch of strings, then getting another array set and then appending that to an external array.
If you really wanted to get a single dimensional array without having this multidimensional thing going on, all you really need to do is utilize another loop within that loop.
$all_tags = array();
while ($row_tags = mysql_fetch_assoc($r_tags)) {
$tags = $row_tags['tags'];
$imploded_tags[] = explode("|",$tags);
for($i = 0; $i < count($imploded_tags); $i++) {
$all_tags[] = $imploded_tags[$i]
}
}
print_r($all_tags);

PHP - Multi line random array

Say we have an array like this with 1 being two values and 2 being two values and 3, etc
$language = array
(
"1"=>array
(
"Hola",
"Spanish"
),
"2"=>array
(
"Fáilte",
"Irish"
),
"3"=>array
(
"Yasou",
"Greek"
)
);
How would I randomly select ONLY 1 of 3 arrays and display the two values it has.
So something like this, $language[2][1], thats in $language[2][2].
Which should be, Fáilte, thats in Greek
PHP has it's own random array function: array_rand(). Use it like so:
$random_key = array_rand($language);
echo $language[$random_key][0];
echo $language[$random_key][1];
You can choose a random set of words using the following code and then echo the two results like so:
$row = rand(0,sizeof($language)-1);
echo $language[$row][0];
echo $language[$row][1];
This is assuming that your array actually starts from 0 as most arrays do. If it really starts from 1, you can use the code posted in the answer below instead.

Categories