Not sure if I titled this question correctly. I'm having some trouble looping over a multi-demensional php array to build some HTML nodes. Here is the array I'm looping over:
$locations = array(
'CityName' => array(
array(
'title' => 'Title',
'phone' => '(555) 555-5555',
'address' => '1234 Fake st.',
'city' => 'Ventura',
'state' => 'CA',
'zip' => '93003',
'url' => 'http://www.google.com/'
),
array(
'title' => 'Title',
'phone' => '(555) 555-5555',
'address' => '1234 Fake st.',
'city' => 'Ventura',
'state' => 'CA',
'zip' => '93003',
'url' => 'http://www.google.com/'
),
),
'CityName2' => array(
array(
'title' => 'Title',
'phone' => '(555) 555-5555',
'address' => '1234 Fake st.',
'city' => 'Ventura',
'state' => 'CA',
'zip' => '93003',
'url' => 'http://www.google.com/'
),
array(
'title' => 'Title',
'phone' => '(555) 555-5555',
'address' => '1234 Fake st.',
'city' => 'Ventura',
'state' => 'CA',
'zip' => '93003',
'url' => 'http://www.google.com/'
)
)
);
Keep in mind I may have built this array incorrectly for what I'm trying to do. The HTML output for this loop should be:
<h4>CityName</h4>
<ul>
<li>
<p>Title</p>
<p>1234 Fake St.</p>
<p>Ventura, CA 93003</p>
<p>(555) 555-5555</p>
<p class="link">Visit Website</p>
</li>
<li>
<p>Title</p>
<p>1234 Fake St.</p>
<p>Ventura, CA 93003</p>
<p>(555) 555-5555</p>
<p class="link">Visit Website</p>
</li>
</ul>
<h4>CityName2</h4>
<ul>
...
</ul>
I think what I want to do is to be able to grab the individual pieces of data to plug into my HTML template.. like $location['title'], $location['phone'], etc. The PHP that I currently have will only go as far to loop over and echo out the keys or values from each individual location array.
<?php
// Printing all the keys and values one by one
$locationNames = array_keys($locations);
for($i = 0; $i < count($locations); $i++) {
echo "<h4>" . $locationNames[$i] . "</h4>";
echo "<ul>";
foreach($locations[$locationNames[$i]] as $key => $value) {
foreach($value as $key => $value) {
echo $value;
}
}
echo "</ul>";
}
?>
Use nested foreach loops amd drop the values in to the appropriate places:
<?php foreach ($locations as $location => $ldata) { ?>
<h4><?php echo $location; ?></h4>
<ul>
<?php foreach ($ldata as $attribute) { ?>
<li>
<p><?php echo $attribute['title']; ?></p>
<p><?php echo $attribute['address']; ?></p>
<p><?php echo $attribute['city'] . " ," . $attribute['state'] . " " . $attribute['zip']; ?></p>
<p><?php echo $attribute['phone']; ?></p>
<p class="link">Visit Website</p>
</li>
<? php } ?>
<?php } ?>
You just need nested (foreach) loops:
<?php foreach($locations as $cityname => $location):?>
<h4><?=$cityname?></h4>
<ul>
<?php foreach($location as $place:?>
<li>
<p><?=$place['title']?></p>
<p><?=$place['phone']?></p>
<!-- etc etc-->
</li>
<?php endforeach;?>
</ul>
<?php endforeach;?>
Something like this should work. I won't implement the HTML for you, but you it should be easy to do. This has the advantage that if you have dynamic keys in the inner array, you won't have to know them before hand.
foreach($locations as $key => $value) {
echo $key, PHP_EOL;
$data = $locations[$key];
$length = count($data);
for($i = 0; $i < $length; $i++) {
$values = $data[$i];
foreach($values as $key2 => $value2)
echo "\t", $key2, ": ", $value2, PHP_EOL;
}
}
Just a few tweaks to your code:
<?php
// Printing all the keys and values one by one
$locationNames = array_keys($locations);
for($i = 0; $i < count($locations); $i++) {
echo "<h4>" . $locationNames[$i] . "</h4>";
echo "<ul>";
foreach($locations[$locationNames[$i]] as $key => $value) {
echo "<li>"; // add list open tag <-- tweak #1
foreach($value as $key => $value) {
echo "<p>$value</p>"; // add paragraph tags <-- tweak #2
}
echo "</li>"; // add list close tag <-- tweak #3
}
echo "</ul>";
}
?>
PHP Sandbox example.
Related
I am trying to sort SQL results into different divs based on the category they are assigned in the database. There are four categories and it works fine as long as there are videos available for all 4 categories. It will create 1 div for each and assign the videos to the correct div. The issue I'm having is that I'd like to also create the div even if there are no videos available within that category. (Pretty new so the code is probably pretty chunky for what it should be)
PHP code
$stmt = $conn->prepare("SELECT * FROM VIDEOS WHERE categorie=:category ORDER BY categorie ASC, subcategorie ASC");
$stmt->bindParam(':category', $_POST['category']);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "<div class='spacer'>";
$testcase = "";
for($x = 0; $x < sizeof($result); $x++) {
if($result[$x]["subcategorie"] != $testcase) {
echo
"</div><div class='subcategory_container active' id='" . $result[$x]["subcategorie"] . "'>
<h3 class='subcategory_title'>". $result[$x]["subcategorie"] . "</h3>";
echo
"<div class='video_div'> <iframe width='196' height='350'
src='" . $result[$x]['linkembed'] . "'>
</iframe></div>";
$testcase = $result[$x]["subcategorie"];
} else {
echo
"<div class='video_div'> <iframe width='196' height='350'
src='" . $result[$x]['linkembed'] . "'>
</iframe></div>";
}
}
I have tried adding multiple if($result[$x]["subcategorie"] == "categoryname") statements but specifying the name within a for loop resulted in there being multiple of the same divs and a repeat of data. So far I've tried to look up SQL group by PHP tutorials but they all show the same result being inside of a table. The goal is to get the information into their own div with the ID of said div being the category name. I'm working with AJAX calls using JS to fix the issue won't work.
This solution builds a $videos array using the static subcategories as keys, it then populates these after looking through the database, then it's a matter of echoing the iframes if records exist.
<?php
/*
Question Author: Terhert
Question Answerer: Jacob Mulquin
Question: PHP SQL Sorting information into HTML div elements
URL: https://stackoverflow.com/questions/74715867/php-sql-sorting-information-into-html-div-elements
Tags: php, mysql
*/
include '../../inc/helpers.php';
try {
$pdo = new PDO(DB_DSN, DB_USER, DB_PASS, DB_OPTIONS);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
$pdo->query('DROP TABLE table74715867;');
$pdo->query('CREATE TABLE IF NOT EXISTS table74715867 (id TEXT, name TEXT, linkembed TEXT, categorie TEXT, subcategorie TEXT);');
$data = [
['id' => '1', 'name' => 'test1','linkembed' => 'http://example.org', 'categorie' => 'abc', 'subcategorie' => 'kracht'],
['id' => '2', 'name' => 'test2','linkembed' => 'http://example.org', 'categorie' => 'abc', 'subcategorie' => 'uithouding'],
['id' => '9', 'name' => 'test9','linkembed' => 'http://example.org', 'categorie' => 'abc', 'subcategorie' => 'mobiliteit'],
['id' => '10', 'name' => 'test10','linkembed' => 'http://example.org', 'categorie' => 'abc', 'subcategorie' => 'mobiliteit'],
['id' => '3', 'name' => 'test3','linkembed' => 'http://example.org', 'categorie' => 'xyz', 'subcategorie' => 'majig1'],
['id' => '4', 'name' => 'test4','linkembed' => 'http://example.org', 'categorie' => 'xyz', 'subcategorie' => 'majig2'],
['id' => '5', 'name' => 'test5', 'linkembed' => 'http://example.org', 'categorie' => '123', 'subcategorie' => 'whatchmacallit1'],
['id' => '6', 'name' => 'test6', 'linkembed' => 'http://example.org', 'categorie' => '123', 'subcategorie' => 'whatchmacallit2'],
['id' => '7', 'name' => 'test7', 'linkembed' => 'http://example.org', 'categorie' => 'qwerty', 'subcategorie' => 'fizz1'],
['id' => '8', 'name' => 'test8', 'linkembed' => 'http://example.org', 'categorie' => 'qwerty', 'subcategorie' => 'buzz1'],
];
$stmt = $pdo->prepare('INSERT INTO table74715867 SET id=:id, name=:name, linkembed=:linkembed, categorie=:categorie, subcategorie=:subcategorie;');
foreach ($data as $record) {
$stmt->execute([
':id' => $record['id'],
':name' => $record['name'],
':linkembed' => $record['linkembed'],
':categorie' => $record['categorie'],
':subcategorie' => $record['subcategorie']
]);
}
$category = 'abc';
$stmt = $pdo->prepare("SELECT * FROM table74715867 WHERE categorie=:category ORDER BY categorie ASC, subcategorie ASC");
$stmt->bindParam(':category', $category);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$videos = ["kracht" => [], "uithouding" => [], "mobiliteit" => [], "stretching" => []];
foreach ($result as $record) {
$videos[$record['subcategorie']][] = $record;
}
foreach ($videos as $subcategory => $records) {
echo '<div class="subcategory_container active" id="' . $subcategory . '">' .
'<h3 class="subcategory_title">' . $subcategory . '</h3>';
if (!empty($records)) {
foreach ($records as $record) {
echo '<div class="video_div"><iframe width="196" height="350" src="'.$record['linkembed'].'"></iframe></div>';
}
}
echo '</div>';
}
Here's the resulting HTML:
<head></head>
<body>
<div class="subcategory_container active" id="kracht">
<h3 class="subcategory_title">kracht</h3>
<div class="video_div">
<iframe src="http://example.org" width="196" height="350"></iframe>
</div>
</div>
<div class="subcategory_container active" id="uithouding">
<h3 class="subcategory_title">uithouding</h3>
<div class="video_div">
<iframe src="http://example.org" width="196" height="350"></iframe>
</div>
</div>
<div class="subcategory_container active" id="mobiliteit">
<h3 class="subcategory_title">mobiliteit</h3>
<div class="video_div">
<iframe src="http://example.org" width="196" height="350"></iframe>
</div>
<div class="video_div">
<iframe src="http://example.org" width="196" height="350"></iframe>
</div>
</div>
<div class="subcategory_container active" id="stretching">
<h3 class="subcategory_title">stretching</h3>
</div>
</body>
i have an array i and i want to show the array values if the name of same array repeat in the another array and have true value
my arrays like this
$array1 = [
array(
'name' => internal_evidence
'price' => 30
'course_id' => 3
),
array(
'name' => international_evidence
'price' => 450
'course_id' => 3
),
array(
'name' => internal_evidence
'price' => 10
'course_id' => 1
),
array(
'name' => technical_evidence
'price' => 134
'course_id' => 3
),
];
$array2 = [
array(
'id' => 3
'name' => graphic
'price' => 150
'attr' => array(
'internal_evidence' => 'true',
'international_evidence' => 'false',
'technical_evidence' => 'true'
)
),
array(
'id' => 5
'name' => 3dmax
'price' => 300
'attr' => array(
)
),
array(
'id' => 1
'name' => ICDL
'price' => 480
'attr' => array(
'internal_evidence' => 'true',
)
),
];
i want to showing this all attr selected with true value in like this
also I want to sum price of array2 member and array1
<h2>graphic</h2>
<p>internal_evidence</p>
<p>technical_evidence</p>
<small>course price: 150</small>
<small>314</small> <!-- Price with selected evidence -->
<h2>3dmax</h2>
<small>course price: 300</small>
<!-- its not have attr evidence -->
<h2>ICDL</h2>
<p>internal_evidence</p>
<small>course price: 480</small>
<small>490</small> <!-- Price with selected evidence -->
i try this but its don`t work properly
$priceOfAttr = 0;
foreach($array2 as $key => $cat):
echo "<h2>{$cat['name']}</h2>";
foreach($array1 as $pr):
if($pr['course_id'] == $cat['id']):
foreach($cat['attr'] as $m => $optionV):
if($m == $pr['name'] && $optionV == "true"){
echo $m .'<br>';
$priceOfAttr += $pr['price'];
// echo "<small>{$cat['price']}</small><br>";
// echo $cat['price'] + $pr['price']. "<br>";
}
endforeach;
echo $priceOfAttr + $cat['price'] . '<br>';
endif;
endforeach;
echo '<br>';
endforeach;
I'd use a combination array_reduce and array_map to transform your data into what you need, then simply loop over that to display your view:
<?php
// Index your $array1 by [id][name]
$array1ByIdAndName = array_reduce($array1, static function ($byIdAndName, $entry) {
$byIdAndName[$entry['course_id']][$entry['name']] = $entry;
return $byIdAndName;
});
// Transform $array2's `attr` entries into attribute list + compute total price
$array2 = array_map(static function ($entry) use ($array1ByIdAndName) {
$entry['total_price'] = $entry['price'];
$entry['attr'] = array_reduce(array_keys($entry['attr']), static function ($attrs, $attrName) use ($array1ByIdAndName, &$entry) {
if ($entry['attr'][$attrName] === 'true') {
$attrs[] = $attrName;
$entry['total_price'] += $array1ByIdAndName[$entry['id']][$attrName]['price'];
}
return $attrs;
}, []);
return $entry;
}, $array2);
// Display your view
?>
<?php foreach ($array2 as $entry): ?>
<h2><?= $entry['name'] ?></h2>
<?php foreach ($entry['attr'] as $attrName): ?>
<p><?= $attrName ?></p>
<?php endforeach ?>
<small>course price : <?= $entry['price'] ?></small>
<?php if ($entry['total_price'] > 0): ?>
<small><?= $entry['total_price'] ?></small>
<?php endif ?>
<?php endforeach ?>
Demo: https://3v4l.org/nS3Gl
I have an array like this:
$files = array(
array(
'name' => 'Detailed Brief - www.xyz.com.pdf',
'size' => '1.4MB',
),
array(
'name' => 'Pure WordPress theme.zip',
'size' => '735.9KB',
),
array(
'name' => 'Logotype.jpg',
'size' => '94.7KB',
),
);
How can I display the information as follows:
ul - li
Detailed Brief...- pdf(1.4mb)
Pure Wordpress... - zip(735.kb)
Logotype.jpg-(94,7kb)
Any ideas? I'm trying all the time with foreach but it's not working.
It is simple:
<ul>
<?php foreach ($files as $key => $file): ?>
<li><?php echo $file['name'] . ' - ' . $file['size'] ?></li>
<?php endforeach ?>
</ul>
The other answer is not quite what you're looking for. For each iteration of the loop, you want the filename, the file extension, and the file size:
<ul>
<?php
foreach ($files as $key => $file) {
$f = pathinfo($file['name']);
echo '<li>';
echo $f['filename'].' - '.$f['extension'].'('.$file['size'].')';
echo '</li>';
}
?>
</ul>
I've got an multidimensional array with some values.
[
1 => [
'label' => 'SEO',
'content' => 'Some content',
'group' => 'We can offer'
]
2 => [
'label' => 'Webdesign',
'content' => 'Some content',
'group' => 'We can offer'
]
3 => [
'label' => 'Contact',
'content' => 'Some content',
'group' => 'Who are we?'
]
4 => [
'label' => 'Logodesign',
'content' => 'Some content',
'group' => 'We can offer'
]
5 => [
'label' => 'Address',
'content' => 'Some content',
'group' => 'Who are we?'
]
]
The group element is a variety of user input. I want to sort all group elements what are the same into the same array. It's then going to be displayed. If there are only 2 elements with the same group value, then there will only be two columns (50% width on both) in a .row element in HTML, if there are 1 element, only one column (100% width). I'm trying to build a very simple CMS if anyone was wondering why. There may be more easier ways to do this, but I can't think of any.
Any help is appreciated.
EDIT:
I just got the array sorted i think. It looks right.
Now I just need to display it the right way.
$i = 0;
$count = count($data['sections']);
$content = [];
for ($i = 0; $i < $count; $i++) {
if (!in_array($data['sections'][$i]['group'], $content)) {
$content[] = $data['sections'][$i]['group'];
}
$content[$data['sections'][$i]['group']][] = ['label' => $data['sections'][$i]['label'], 'content' => $data['sections'][$i]['content']];
}
Group the array
Simply loop through the array and put all the elements into a new, nested array:
$content = array();
foreach($data['sections'] as $section) {
$content[$section['group']][] = $section;
}
This gives you an array $content of this format:
[
'We can offer' => [
1 => [
'label' => 'SEO',
'content' => 'Some content',
'group' => 'We can offer'
]
2 => [
'label' => 'Webdesign',
'content' => 'Some content',
'group' => 'We can offer'
]
...
]
'Who are we?' => [
...
]
]
Divide the width: Table display
So how do you output this so that every category gets equal width? First you need to loop through the nested array to print some HTML:
<div class="outer">
<?php foreach($content as $group) { ?>
<div class="row">
<?php foreach($group as $item) { ?>
<div class="item"><?php echo $item['content']; ?></div>
<?php } ?>
</div>
<?php } ?>
</div>
Have a look at this answer for one way to do it using CSS:
div.outer { display:table; }
div.row { display:table-row; }
div.item { display:table-cell; }
Divide the width: Explicit width
Another way to do it is to calculate the width in percentage in PHP and set it explicitly with the width attribute:
<?php foreach($content as $group) { ?>
<div class="row">
<?php $w = 100 / count($group); ?>
<?php foreach($group as $item) { ?>
<div class="item" width="<?php echo $w; ?>%">
<?php echo $item['content']; ?>
</div>
<?php } ?>
</div>
<?php } ?>
I have a multi dimensional array that is printing out exactly how I want it, however, I have become stuck on figuring out how I can construct it into the for each loop that i'm looking for.
Please Note : $handle is a field the client entered in the backend.
<?php
$gp = Mage::getStoreConfig('social_code/social_group/google_field');
$ld = Mage::getStoreConfig('social_code/social_group/linkedin_field');
$tw = Mage::getStoreConfig('social_code/social_group/twitter_field');
$fb = Mage::getStoreConfig('social_code/social_group/facebook_field');
$social_array = array(
"facebook" => array(
'class' => "facebook",
'url' => 'https://www.facebook.com/',
'handle' => $fb
),
"twitter" => array(
'class' => "twitter",
'url' => 'https://www.twitter.com/',
'handle' => $tw
),
"linked-in" => array(
'class' => "linked-in",
'url' => 'http://www.linkedin.com/company/',
'handle' => $ld
),
"google-plus" => array(
'class' => "google-plus",
'url' => 'https://plus.google.com/',
'handle' => $gp
)
);
?>
Now i wish to spit this out as an unordered list so i have the below, but its still not working for me.
<ul>
<?php foreach ($social_array as $name => $group) :?>
<?php foreach ($group as $class => $url) :?>
<li><?php echo ("$group"); ?></li>
<?php endforeach; ?>
<?php endforeach; ?>
</ul>
I would like it so that it loops through all the social array and prins something similar to this
<li><?php echo $name; ?></li>
or so understood better
<li>Facebook</li>
Also if I'm making this over complicated for myself please let me know.
<ul>
<?php foreach ($social_array as $name => $group) :?>
<li><?php echo $name; ?></li>
<?php endforeach; ?>
</ul>
I think this is what you're looking for if I've understood correctly.
<ul>
<?php foreach ($social_array as $name => $group) :?>
<li><a href="<?php echo $group['url'].$group[handle']; ?>" class="<?php echo $group['class']; ?>"><?php echo $name
<?php endforeach; ?>
</ul>
There is no need to inner foreach.
<?php foreach ($social_array as $name => $group) :?>
<li><?php echo $group['class']; ?></li>
<?php endforeach; ?>
See http://3v4l.org/3cH6f for the example working below. Just one foreach.
<?php
$social_array = array(
"facebook" => array(
'class' => "facebook",
'url' => 'https://www.facebook.com/',
'handle' => 'Mage::getStoreConfig(\'social_code/social_group/twitter_field\')'
),
"twitter" => array(
'class' => "facebook",
'url' => 'https://www.facebook.com/',
'handle' => 'Mage::getStoreConfig(\'social_code/social_group/twitter_field\')'
),
"linked-in" => array(
'class' => "facebook",
'url' => 'https://www.facebook.com/',
'handle' => 'Mage::getStoreConfig(\'social_code/social_group/twitter_field\')'
),
"google-plus" => array(
'class' => "facebook",
'url' => 'https://www.facebook.com/',
'handle' => 'Mage::getStoreConfig(\'social_code/social_group/twitter_field\')'
)
);
$html = '<ul>';
foreach ($social_array as $name => $class_array){
$html .= '<li>'. $name. '</li>';
}
$html .= '</ul>';
print $html;
?>
Give this a shot:
<ul>
<?php foreach ($social_array as $name => $properties) :?>
<li><?php echo ucfirst($name); ?></li>
<?php endforeach; ?>
</ul>
In this foreach, the syntax is foreach($array as $key => $value), so here $name is the key from $social_array, and $properties is the array associated with that key.
The thing you are forgetting is that the inner foreach is processing each item i.e. class,ulr,handle one at a time.
You therefore need to store the information you require as you pass over each of the 3 items so it can be used once you have the 2 items you actually need.
So this may help.
<ul>
<?php
foreach ($social_array as $name => $group) :
$class = NULL;
$url = NULL;
$handle = NULL;
foreach ($group as $name => $value) :
switch ($name) :
case 'class' : $class = $value; break;
case 'url' : $url = $value; break;
case 'handle' : $handle = $value; break;
endswitch;
if ( isset($class) AND isset($url) AND isset($handle) ) :
echo '<li>' . $group . '</li>';
$class = NULL;
$url = NULL;
$handle = NULL;
endif;
endforeach;
endforeach;
?>
</ul>