Using this sample multidimensional array (of a palette which contains colours, which in turn contains their respective shades), let’s say I would like to display the colours in an imploded list (comma-separated) and, if applicable, its respective shades in brackets, also in an imploded (comma-separated) list.
I can easily implode the inner array (shades), but cannot figure out how to do that with the outer array (colours) given it contains the array of shades which must be run through for each colour.
I’ve seen there are several solutions for imploding a multidimensional array, but these seem to be without requiring running through a possible inner array for each. Perhaps there is another method by which to separate the entries with a comma?
And while I’m on the subject, is there a way of replacing the last comma of an imploded string with ‘and’?
Thanks in advance.
$sql = "SELECT DISTINCT colour_id, colour_nm, colour_url
FROM palettecolours
INNER JOIN colour ON colourid = colour_id
WHERE paletteid = '$palette_id'";
while ($row = mysqli_fetch_array($result))
{
$colour = '' . $row['colour_url'] . '';
$colours[$row['colour_id']] = array('colour' => $colour, 'shades' => array());
}
$sql = "SELECT colourid, shade_name, shade_url
FROM palettecolours
INNER JOIN shade ON shadeid = shade_id
WHERE paletteid = '$palette_id'";
while ($row = mysqli_fetch_array($result))
{
$shade = '' . $row['shade_url'] . '';
$colours[$row['colourid']]['shades'][] = array('shade' => $shade);
}
<?php foreach ($colours as $colour): ?>
<?php echo $colour['colour']; ?>
<?php if(!empty($colour['shades'])) { ?>(<?php echo implode(", ", $colour['shades']); ?>)<?php } ?>
<?php endforeach; ?>
CURRENT DISPLAY:-
Red (Magenta, Burgundy, Crimson) Blue Green Yellow (Egyptian Cotton, Magnolia) White (Soft Moon)
DESIRED OUTCOME:-
Red (Magenta, Burgundy, Crimson), Blue, Green, Yellow (Egyptian Cotton, Magnolia), White (Soft Moon)
How about recursive functions? Something like
function array_implode_recursive($glue, $data, $before = '(', $after = ')') {
//Loop through every child and check whether it is an array or not and implode it if so
foreach($data as &$element) {
if (is_array($element)) {
$element = $before . array_implode_recursive($glue, $element) . $after;
}
}
//It's really safe to erase this variable as sometimes PHP has fun with them
unset($element);
return implode($glue, $data);
}
Use it like this
$mydata = implode_recursive(', ', $data);
$mydata = implode_recursive(', ', $data, '[', ']');
Hope it helped
Since you know what your array looks like and it appears to have keys you could try something similar to what I've done here.
Related
I've just added a loop to code I already have working. I'm pretty sure what's giving me the trouble, and that is one of the following pieces of code:
First I have:
$teams = array(ARI, ATL, BAL, BUF, CAR, CHI, CIN, CLE, DAL, DEN, DET, GB, HOU, IND, JAC, KC, MIA, MIN, NE, NO, NYG, NYJ, OAK, PHI, PIT, SD, SEA, SF, STL, TB, TEN, WAS);
foreach ($teams as $value) {
$query_string = 'api_key='.$api_key.'&team=$value'; // Change team/month
Is this the right way to set up $query_string to a $value that's changing as the loop runs?
Later inside the loop I have:
$sql = "CREATE TABLE $value . _GAMES ( ". // Creating a new table for each team
Is this the right way to concatenate the $value variable being changed by the loop with the rest of what I want the table name to be? (i.e. I want the first loop to create the table ARI_GAMES.
Change the $query_string to
$teams = array('ARI', 'ATL', 'BAL', 'BUF');
foreach ($teams as $value) {
$query_string = 'api_key='.$api_key.'&team='.$value;
}
Using quotes and curly brackets will be good
$teams = array('ARI', 'ATL', 'BAL', 'BUF');
foreach ($teams as $value) {
$query_string = "api_key={$api_key}&team={$value}";
//sql
$sql = "CREATE TABLE {$value}_GAMES (.... ";
}
I think my dear friend you need little more to learn regarding PHP arrays.
First your $teams array must be an array with strings which are the names of the teams as follows(Note: I have shorten the list of teams array):
$teams = array("ARI", "ATL", "BAL", "BUF", "CAR", "CHI", "CIN", "CLE", "DAL", "DEN", "DET");
So then you need to understand how the PHP concatenation works. For an example, it goes as follows:
$someVar = 5;
$concatenateVar = $someVar.' myOtherStringHere '.$someVar;
echo $concatenatedVar;
will print out following line:
5 myOtherStringHere 5
However I've written the required code specifically for your question. Please try to understand it and learn from it.
<?php
$teams = array("ARI", "ATL", "BAL", "BUF", "CAR", "CHI", "CIN", "CLE", "DAL", "DEN", "DET");
$api_key = "API_KEY_HERE";
foreach ($teams as $value) {
echo "start of another foreach-loop round<br/>";
$query_string = 'api_key = '.$api_key.' team = '.$value;
echo $query_string;
echo "<br/>";
$sql = "CREATE TABLE $value._GAMES ( "; // Creating a new table for each team
echo $sql;
echo "<br/>end of a foreach-loop round<br/>";
}
?>
I want to break comma seperated values which are retrieved from database and then put each individual in a string and print it in a for loop only. I am getting the values from database but i am not be able to break values. Below is the code what i have done right till now.Please help to solve my issue. Thanks in advance.
$query="select * from create_segment";
$result = mysql_query($query,$link) or die(mysql_error());
$number_of_segment=mysql_num_rows($result);
while($row=mysql_fetch_assoc($result))
{
$segments[]=$row;
}
foreach($segments as $success) {
$thePostIdArray = explode(', ', $success['subjects']);
for($i=0; $i < count($thePostIdArray); $i++)
{
echo "string...".$strings=$thePostIdArray[$i];
}
}
It output:
string...1,2,3,4,5,6,7,8,9,10
string...1,2,3,4,5,6,7,8
but i want something like this:
for(......)
{
echo "values...".$i;
}
which should output
values...1
values...2
values...3 and so on.
my database structure is like:
id subjects
1 1,2,3,4,5
2 1,2,7
Please try to use ',' instead of ', ' in your
explode(', ', $success['subjects']);
statement so it would look like:
explode(',', $success['subjects']);
Use:
explode(',', $success['subjects'])
You had a space after the comma, but there are no spaces in the database values.
If you have the opportunity to change the database structure you should convert that table into something like this:
Id Subject
1 1
1 2
1 3
2 1
etc.
It will make your queries much easier, and it the right way to go. It will also make it easier for you in the future do join this table with other tables to get the desired results. I know this doesn't answer your questions, but some good advice will never hurt. One of the other answers will answer your question directly.
$query="select * from create_segment";
$result = mysql_query($query,$link) or die(mysql_error());
$number_of_segment=mysql_num_rows($result);
while($row = mysql_fetch_assoc($result))
{
foreach (explode(',',$row['subjects']) as $value){
echo echo "string... {$row['id']} " . $value . '<br />';
}
}
I've been wrestling with a really cool script someone gave me, trying to adapt it to my site. I'm getting closer, but I'm still getting two errors that have me puzzled.
First: Warning: Invalid argument supplied for foreach()...
This is the foreach statement:
foreach ($Topic as $Topics)
It follows a function:
function generate_menu_items($PopTax, $Topics, $Current_Topic)
I THINK the problem relates to the middle value in the function - $Topics. I don't understand how it's derived. My guess is it's supposed to be an array of all the possible topics (represented by $MyTopic in my database). But I'm not that familiar with functions, and I don't understand why he put the function and foreach BEFORE the database queries. (However, there is a more general DB query that establishes some of these values higher up the food chain.)
Here's the second problem: Fatal error: Call to undefined function render_menu()...
Can anyone tell me how and where I should define this function?
Let me briefly explain what this script is all about. First imagine these URL's:
MySite/topics/animal
MySite/topics/animal-homes
MySite/topics/animal-ecology
MySite/topics/mammal-ecology
MySite/topics/bird-ecology
Two key values are associated with each URL - $PopTax (popular name) and $MyTopic. For the first three URL's, $PopTax = Animal, while the other two are Mammal and Bird. $MyTopic = Ecology for the last three rows. For the first two, $MyTopics = Introduction and Homes.
The ID's for both values (Tax_ID and Topic_ID) are simply the first three letters of the name (e.g. Mam = Mammal, Eco = Ecology). Also, Life is the Parent of Animal, which is the Parent of Vertebrate, which is the Parent of Mammal.
Now I'm just trying to pull it all together to create a little index in the sidebar. So if you visit MySite/topics/animal-ecology, you'd see a list of ALL the animal topics in the sidebar...
Animals
Animal Classification
Animal Homes
Animal Ecology
As you can see there are some case and plural differences (animal vs Animals), though I don't think that really relates to the problems I'm having right no.
But I'm not sure if my code just needs to be tweaked or if there's something grotesquely wrong with it. Something doesn't look right to me. Thanks for any tips.
$Tax_ID = 'Mam'; // Mam represents Mammal
$Current_Topic = 'Homes';
function generate_menu_items($PopTax, $Topics, $Current_Topic)
{
$menu_items = array();
foreach ($Topic as $Topics)
{
$url = "/topics/$PopTax[PopTax]-$Topic[MyTopic]";
$title = "$PopTax[PopTax] $Topic[MyTopic]";
$text = $Topic['MyTopic'];
if ($Topic === 'People') {
$url = "$PopTax[PopTax]-and-$Topic[MyTopic]";
$title = "$PopTax[PopTax] and $Topic[MyTopic]";
$text = "$PopTax[PopTax] & $Topic[MyTopic]";
}
if ($Topic === 'Movement' && $PopTax['Parent'] == 'Ver' && $PopTax['PopTax'] != 'Human') {
$url = "$PopTax[PopTax]-locomotion";
$title = "$PopTax[PopTax] Locomotion";
$text = "Locomotion";
}
$menu_items[] = array(
'url' => strtolower($url),
'title' => ucwords($title),
'text' => ucfirst($text),
'active' => ($Topic['MyTopic'] === $Current_Topic)
);
}
return $menu_items;
}
function generate_menu_html($menu_items)
{
$list_items = array();
foreach ($menu_items as $item)
{
if ($item['active']) {
$list_items[] = "<li><span class=\"active\">$item[text]</b></span></li>";
} else {
$list_items[] = "<li>$item[text]</li>";
}
}
return '<ol>' . implode("\n", $list_items) . '</ol>';
}
$stm = $pdo->prepare("SELECT T.Topic_ID, T.MyTopic
FROM gz_topics T
JOIN gz_topics_poptax TP ON TP.Topic_ID = T.Topic_ID
WHERE TP.Tax_ID = :Tax_ID");
$stm->execute(array('Tax_ID' => $Tax_ID));
// Fetch all rows (topics) as an associative array
$Topics = $stm->fetchAll(PDO::FETCH_ASSOC);
// Get the DB row for the taxon we're dealing with
$stm = $pdo->prepare("SELECT Tax.ID, Tax.PopTax, Tax.Parent
FROM gz_poptax Tax
WHERE Tax.ID = :Tax_ID");
$stm->execute(array('Tax_ID' => $Tax_ID));
// Fetch a single row, as the query should only return one row anyway
$PopTax = $stm->fetch(PDO::FETCH_ASSOC);
// Call our custom functions to generate the menu items, and render them as a HTML list
$menu_items = generate_menu_items($PopTax, $Topics, $Current_Topic);
$menu_html = render_menu($menu_items);
// Output the list to screen
echo $menu_html;
You want foreach ($Topics as $Topic). You are looping over each $Topic in $Topics is another way to think of it.
I'm trying to combine several results from an array into one variable.
$sqlNameForCode = "Select dim_InvoiceRef from dimensions"." Where dim_FileRef = '".$addRow[$FieldName]."'";
$qryNameForCode = mysql_Query($sqlNameForCode);
While($arrNameForCode = mysql_fetch_array($qryNameForCode)) {
$addRow[$FieldName] = $arrNameForCode['dim_InvoiceRef'];
}
I need the variable $addRow[$FieldName] to contain all the fields taken from the array. However because it's within the While loop only the last field is ever left in the variable.
Example, the query pulls the following results
Apple
Banana
Orange
I need echo $addRow[$FieldName] to show Apple Banana Orange, at the moment it just equals Orange.
Any help would be great thanks!
You need to make it into an array
While($arrNameForCode = mysql_fetch_array($qryNameForCode)) {
$addRow[$FieldName][] = $arrNameForCode['dim_InvoiceRef']; //notice the extra braces
}
echo implode(' ', $addRow[$FieldName]); //prints the values in the array separated by a space
Or directly assign it to a string
$addRow[$FieldName] = "";//defaults
While($arrNameForCode = mysql_fetch_array($qryNameForCode)) {
$addRow[$FieldName] .= $arrNameForCode['dim_InvoiceRef']; //string concatenation
}
echo $addRow[$FieldName];
Here's a MySQL-based solution that you might find easier:
$sql = "SELECT GROUP_CONCAT(dim_InvoiceRef SEPARATOR ' ') FROM dimensions WHERE dim_FileRef = '".$field."'";
$query = mysql_query($sql);
$result = mysql_fetch_row($query);
echo $result[0]; // Should show 'Apple Orange Banana' etc.
I took the liberty of renaming some variables in your example to make it easier to understand. Unless you need to do different things with the same data later on in the program, this should work.
I'm trying to make a simple alphabetical list to order items in my database. The thing I can't figure out is how to actually list it.
I would like it to be the same format as you have on miniclip.com
Here's an image
I looked around, but couldnt find an answer really.
(I would like it to finish even at the end of each vertical column, except the last one for sure)
Any help would be welcome!
In MySQL:
SELECT * FROM table ORDER BY name ASC
In PHP:
$fruits = array("lemon", "orange", "banana", "apple");
sort($fruits);
foreach ($fruits as $key => $val) {
echo "fruits[" . $key . "] = " . $val . "\n";
}
fruits[0] = apple
fruits[1] = banana
fruits[2] = lemon
fruits[3] = orange
Assuming that your result set already is sorted by using the ORDER BY clause, to group the results by their first character you just need to remember the first character of the previous entry and print out the first character of the current entry if they are different. So:
$prevLabel = null;
while ($row = mysql_fetch_assoc($result)) {
$currLabel = strtoupper(substr($row['name'], 0, 1));
if ($currLabel !== $prevLabel) {
echo $currLabel;
$prevLabel = $currLabel;
}
echo $row['name'];
}
This will print the first character as a label for each group that’s members have the same first character.
He doesn't seem to have an issue with the storting, but doing the column format and headers for each new letter.
Suppose $arr contains your alphabetically sorted list with numeric keys. each element has indexes 'name' and 'link'. This should be pretty safe assumption for data from a SQL query.
$firstLetter = -1;
$desiredColumns = 4; //you can change this!
$columnCount = (count($arr)+27)/$desiredColumns+1;
echo "<table><tr><td>";
foreach($arr as $key => $cur)
{
if ($key != 0 && $key % desiredColumns == 0) echo "</td><td>";
if ($cur['name'][0] !== $firstLetter)
{
echo "<strong>$firstLetter</strong> <br />"; $firstLetter = $cur['name'][0];
}
echo "".$cur['name']."<br />";
}
echo "</td><tr></table>";
You'll have to treat numbers as a special case, but this is the idea. If you are using a template engine there are obviously better ways of doing this, but I figure you would have mentioned that. This is a rough sketch, making pretty HTML isn't my thing.
--Query-- get table into $arr. I can't see your tables obviously, Im making assumptions if names nad stuff so you'll need to verify or change them
$sql = "SELECT * FROM table T ORDER BY name";
$conn = //you should have this
$res = mysql_query($sql, $conn);
$arr = array();
while($row = mysql_fetch_assc($res)
$arr[] = $row;
// start above code here. This isn't safe for empty query responses or other error but it works
I presume you're using MySQL (or another SQL) database, in which case you should simply retrieve the data in the required order using a SORT BY clause on the lookup SELECT. (Sorting this PHP is trivial via the sort function, but it makes sense to get the database to do this - that's pretty much what it's for.)
In terms of balancing the output of each of the columns, you could get a COUNT of the required rows in your database (or simply use the count of the resulting PHP array of data) and use this to ensure that the output is balanced.
As a final thought, if this is going to be output on a per-page basis, I'd highly recommend generating it into a static file when the structure changes and simply including this static file as a part of the output - generating this on the fly is needlessly resource inefficient.
The mysql option mentioned above is definitely the best bet. If the data comes out of the DM in order, that's the simplest way to go.
Your next option might be to look at the
asort and ksort functions in PHP to find the exact one you're looking for.
http://www.php.net/manual/en/array.sorting.php
How are you pulling the data?
<?php
$result = mysql_query("SELECT titles FROM gamelist ORDER BY title ASC");
while ($row = mysql_fetch_assoc($result)) {
echo "{$result['title']}<br/>";
}
?>
There are two ways to do it.
You could use your database and use the 'order' clause to pull them by a specific field alphabetically.
You could also use either a key sort or value sort on a PHP array.
The PHP functions are sort($array) and ksort($array).
http://php.net/manual/en/function.sort.php
http://php.net/manual/en/function.ksort.php
<?php
$list = $your_list_array_from_database
//if you need info on how to do this, just let me know
sort($list);
foreach($list as $item) {
echo $item;
}
?>
I found this post and had the same problem. I used the code below to output a list by category name with a header equal to the first letter. In my database table (category) I have name and category_letter. So, name = football and category_list = 'F'.
<section>
<?php
try {
$cats_sql = $dbo->prepare("SELECT name, category_list, FROM category WHERE category_list REGEXP '^[A-Z#]' GROUP BY category_list ASC");
$cats_sql->execute();
$results_cats = $cats_sql->fetchAll();
} catch(PDOException $e) {
include('basehttp/error');
}
$array_cats = $results_cats;
if(is_array($array_cats)) {
foreach($array_cats as $row_cats) {
$cat_var = $row_cats[category_list]; // Each Category list title
?>
<aside>
<h1><a name=""><? echo $cat_var ?></a></h1>
<?php
try {
$search_sql = $dbo->prepare("SELECT name, category_list FROM category WHERE category_list=:cat_var ORDER BY name ASC"); // Pulling a list of names for the category list
$search_sql->bindParam(":cat_var",$cat_var,PDO::PARAM_STR);
$search_sql->execute();
$results_search = $search_sql->fetchAll();
} catch(PDOException $e) {
include('basehttp/error');
}
$array_search = $results_search;
if(is_array($array_search)) { // Output list of names which match category
foreach($array_search as $row_search) {
?>
<h2><?php echo $row_search[name]; ?></h2>
<br class="clear">
<?php
}
}
?>
</aside>
<br class="clear">
<?php
}
}
?>
</section>
Its actually Simple....I did similar thing for my project once. I had to pull out all music albums name and categorize them in alphabetical order.
In my table, "album_name" is the column where names are stored.
$sql= "select * from album_table order by album_name ASC";
$temp_char= ""; // temporary variable, initially blank;
using while loop, iterate through records;
while($row= $rs->fetch_assoc())
{
$album_name= $row['album_name'];
$first_char_of_albm= $album_name[0]; // this will store first alphabet;
$first_char_of_albm= strtoupper($first_char_of_albm); // make uppercase or lower as per your needs
if($temp_char!=$first_char_of_albm)
{
echo $first_char_of_albm;
$temp_char= $first_char_of_albm; // update $temp_char variable
}
}
That's it....
I am posting my answer to this old question for 3 reasons:
You don't always get to write your queries to MySQL or another DBMS, as with a web service / API. None of the other answers address PHP sorting without query manipulation, while also addressing the vertical alphabetical sort
Sometimes you have to deal with associative arrays, and only a couple other answers deal with assoc. arrays. BTW, my answer will work for both associative and indexed arrays.
I didn't want an overly complex solution.
Actually, the solution I came up with was pretty simple--use multiple tags with style="float:left", inside of a giant table. While I was sceptical that having multiple tbody tags in a single table would pass HTML validation, it in fact did pass without errors.
Some things to note:
$numCols is your desired number of columns.
Since we are floating items, you may need to set the width and min-width of parent elements and/or add some <br style="clear: both" />, based on your situation.
for alternative sorting methods, see http://php.net/manual/en/array.sorting.php
Here's my full answer:
function sortVertically( $data = array() )
{
/* PREPARE data for printing */
ksort( $data ); // Sort array by key.
$numCols = 4; // Desired number of columns
$numCells = is_array($data) ? count($data) : 1 ;
$numRows = ceil($numCells / $numCols);
$extraCells = $numCells % $numCols; // Store num of tbody's with extra cell
$i = 0; // iterator
$cCell = 0; // num of Cells printed
$output = NULL; // initialize
/* START table printing */
$output .= '<div>';
$output .= '<table>';
foreach( $data as $key => $value )
{
if( $i % $numRows === 0 ) // Start a new tbody
{
if( $i !== 0 ) // Close prev tbody
{
$extraCells--;
if ($extraCells === 0 )
{
$numRows--; // No more tbody's with an extra cell
$extraCells--; // Avoid re-reducing numRows
}
$output .= '</tbody>';
}
$output .= '<tbody style="float: left;">';
$i = 0; // Reset iterator to 0
}
$output .= '<tr>';
$output .= '<th>'.$key.'</th>';
$output .= '<td>'.$value.'</td>';
$output .= '</tr>';
$cCell++; // increase cells printed count
if($cCell == $numCells){ // last cell, close tbody
$output .= '</tbody>';
}
$i++;
}
$output .= '</table>';
$output .= '</div>';
return $output;
}
I hope that this code will be useful to you all.