From the following php script:
while($row = mysqli_fetch_array($res, MYSQLI_ASSOC))
{
$category = $row["category"];
$thing = $row["thing"];
echo $category." ".$thing;
echo "<br>";
}
I echo the following lines:
Book book1
Book book2
Chair chair1
Chair chair2
Table table1
but I would like to display as the following result :
Book
book1
book2
Chair
chair1
chair2
Table
table1
I know I have to make a simple loop somewhere here but I don't get the result I want.
Any help would be appreciated. Thanks.
Bonus : I am planning on make all these words clickable to get the them in a variable. If you could insert this tip into your answer it would be nice.
EDIT :
Here is what I tried so far (trying to add also an icon):
while($row = mysqli_fetch_array($res, MYSQLI_ASSOC))
{
foreach($row as $item)
{
echo "<div style='padding-right: 5px' class='glyphicon glyphicon-book'></div>";
echo $item;
echo "<div style='padding-left: 20px'>";
echo "</div>";
echo "<br>";
}
}
$table = array();
while($row = mysqli_fetch_array($res, MYSQLI_ASSOC))
{
if ( !isset( $table[ $row["category"] ] ) ) {
// No category exists, create now
$table[ $row["category"] ] = array();
}
// append to category
$table[ $row["category"] ][] = $row["thing"];
}
// some additional sorting here
/* todo */
print_r($table);
This solution piggybacks off of PHP inherent named keys by "strings" (which behind the scenes are hashed into "buckets". Since your data only shows a data structure that nests one level deep, it is not a recursive solution. But even still, your basic requirement is on category, so will work even if you have a nested data structure.
isset will check if the category exists. If not a new sub array is created which will hold those values.
[] syntax is PHP style to append to an array.
Thanks to #GetSet answer, I could create the right multidimensional array I needed to get the foloowing result:
Array ( [Book] => Array ( [0] => book1 [1] => book2 ) [Chair] => Array ( [0] => chair1 [1] => chair2 ) [Table] => Array ( [0] => table1 ) )
I wanted then to display on a html page like that:
Book
book1
book2
Chair
chair1
chair2
Table
table1
After reading more about PHP arrays, I made out this solution which seem working for me (with the icones):
foreach ($table as $key => $value)
{
echo "<div style='padding-right: 5px; font-size:13px;' class='glyphicon glyphicon-book'></div>";
echo $key;
echo "<div style='height: 2px'></div>";
foreach ($value as $v2)
{
echo "<div style='padding-right: 7px;padding-left: 15px; font-size:11px;' class='fa fa-file-text-o'></div>";
echo $v2;
echo "<div style='height: 5px'></div>";
}
echo "<div style='height: 10px'></div>";
}
Here is the result:
I know have to work on making clickable these words.
Also, I would love to be able to reduce one category by clicking on the book icon but I imagine I have to use JavaScript for that and I don't really know this language.
I'm trying to add an <hr> tag between lines when a new name is encountered.
$conn = new mysqli("localhost", "root", "", "test");
$rs = $conn->query("SELECT * FROM usuarios");
$info = [];
$i = 0;
while($rows = $rs->fetch_array()) {
$info[$i]["pass"] = $rows["pass"];
$info[$i]["name"] = $rows["name_real"];
$i++;
}
// I want to print a line just after the last duplicated value
for($i = 0; $i < count($info) - 1; $i++) {
if($info[$i]["name"] !== $info[$i +1]["name"] && // some duplicate condition) {
$info[$i]["line"] = "<hr>";
};
}
This is the structure of my info array build from the resultset.
Array
(
[0] => Array
(
[pass] => 12
[name] => Martin
)
[1] => Array
(
[pass] => 20
[name] => Martin
)
[2] => Array
(
[pass] => 2
[name] => Martin
)
[3] => Array
(
[pass] => 2
[name] => Alberto
)
)
My desired result would be something like:
<p>Martin<p>
<p>Martin<p>
<p>Martin<p>
<hr>
<p>Alberto<p>
If you don't care what the duplicate names are or how many duplicates exist, and you just want to see whether or not there are any, it looks like it could be simpler code than some of the possible duplicate answers.
Get the names
$names = array_column($array, 'name');
Then check if the full list of names is equal to the unique list.
$has_duplicates = $names != array_unique($names);
Disclaimer: This answer looks odd now. It was provided for Revision 1 of the question. I seem to have misunderstood the question somewhat, and then Revision 2 transformed it to the extent that this answer no longer applies at all. Still, I think it's a useful way to do the thing that it seemed was trying to be done at first.
This solution would be handy:
$result = array();
$names = array_count_values(array_column($source, 'name'));
foreach($names as $key=>$val) {
$result[$key] = ($val == 1 ? false : true);
}
This can be achieved with just one loop. First, use your mysqli query to order the resultset by name_real. (If you are only going to use name_real, you can change the SELECT clause to reflect this. I have shown this in the commented query.) Then write a condition that checks for a new/unique name_real -- if so, echo <hr>.
Code: (Demo)
//$rs = $conn->query("SELECT `name_real` FROM usuarios ORDER BY `name_real`;");
$rs=[
['pass'=>2,'name_real'=>'Alberto'],
['pass'=>12,'name_real'=>'Martin'],
['pass'=>20,'name_real'=>'Martin'],
['pass'=>2,'name_real'=>'Martin']
];
$prev=NULL;
//while($rows = $rs->fetch_array()) {
foreach($rs as $rows){
if($prev && $rows['name_real']!=$prev){ // if not first iteration, and new name_real
echo "<hr>";
}
echo "<p>{$rows['name_real']}</p>";
$prev=$rows['name_real']; // preserve this value for next iteration's check
}
Output:
<p>Alberto</p>
<hr>
<p>Martin</p>
<p>Martin</p>
<p>Martin</p>
I have this code and I want to compare the data that came from db with the one user selects but it seems that the foreach($question_answers as $answer){
and foreach ($user_answer as $key => $value) { it is not good it is repeating for 4 times more, I need a way to compare $user_answer which is what user has selected request from the view, and the $answer['order'] the order comes from database. So I need a loop or something to compare these two.. any help..? thank you.
foreach($questions as $question) {
$question_answers = OrderingAnswer::where('question_id', $question->id)
->where('deleted',0)
->get()
->toArray();
$users_answers = $request->except('_token', 'test_id');
$user_answer = $users_answers[ $question->id];
// $user_answer ---> Array ( [0] => 1 [1] => 4 [2] => 3 [3] => 2 )
foreach ($question_answers as $answer) {
//$answer['order'] ---> 1
foreach ($user_answer as $key => $value) {
if ($answer['order'] == $value ) {
echo "ok ===>" .$value . "<br>" ;
} else {
echo "no -------------------------------- >".$value . "<br>" ;
}
}
}
I have tried this - it is working perfect. (This question was really intresting)
Here basically i am comparing multidimensional array value to a single dimensional array value. it will just give you array of matched results.
<?php
$question_answers= array(
array("id"=>251,'question_id'=>242,'order'=>1),
array("id"=>252,'question_id'=>243,'order'=>2)
);
$user_answers = array(1,4,3,2);
// you can just use this part
$question_answers = array_filter($question_answers, function($arr) use ($user_answers) {
return in_array($arr['order'], $user_answers);
});
echo "<pre>";
print_r($question_answers);
?>
I'm trying to generate an array that will look like this:
Array ( [123 Smith St, Begora] => L1234 [55 Crumble Road, Mosmana] => L2456 [99 Jones Ave, Gestana] => L3456 )
which will ultimately be used for a select menu on an html form.
I'm retrieving a list of records and propertyID numbers from a database as follows:
foreach($records as $record) {
$propertyID = $record->getField('propertyID');
$property = $record->getField('propertyAddress');
echo $propertyID.'<br>';
echo $property.'<br>';
}
which displays like this when I retrieve 3 records:
L1234
123 Smith St, Begora
L2456
55 Crumble Road, Mosmana
L3456
99 Jones Ave, Gestana
I just can't work out how to convert this into an Array which I can then use later on in my page for generating a select menu.
Just do
foreach($records as $record) {
$propertyID = $record->getField('propertyID');
$property = $record->getField('propertyAddress');
$addresses[$property] = $propertyID;
}
Something like this:
$array = array();
foreach($records as $record) {
$array[$record->getField('propertyAddress')] = $record->getField('propertyID');
}
I've read a lot of people discussing nested lists, but I was wondering how to iterate through an adjacancy list/tree in PHP.
I have a table with: id, title, parent_id
And I've selected all records out into an array called $pages.
Then using this php:
function makeList($pages, $used) {
if (count($pages)) {
echo "<ul>";
foreach ($pages as $page) {
echo "<li>".$page['pag_title'];
$par_id = $page['pag_id'];
$subsql("SELECT * FROM pages WHERE pag_parent = ".$par_id."");
// running the new sql through an abstraction layer
$childpages = $dbch->fetchAll();
makeList($childpages, $used, $lastused);
echo "</li>";
}
echo "</ul>";
}
}
This sort of works but I end up with any sub menu being repeated e.g.
HomeNewsSub-newsArticlesArticleNewsSub-newsArticlesArticleSub-newsArticle
I've tried adding the current id into an array that gets passed through the function, and then using in_array to check if it's there, but I have had no joy doing that.
Any help would be much appreciated.
I need to parse the whole tree so choosing parent as 0 isn't an option
Since it already does the SQL, you dont have to do it outside before the first function call.
function makeList($par_id = 0) {
//your sql code here
$subsql("SELECT * FROM pages WHERE pag_parent = $par_id");
$pages = $dbch->fetchAll();
if (count($pages)) {
echo '<ul>';
foreach ($pages as $page) {
echo '<li>', $page['pag_title'];
makeList($page['pag_id']);
echo '</li>';
}
echo '</ul>';
}
}
For storing it more tree like you might want to look at this site: Storing Hierarchical Data in a Database.
If you create an array of pages grouped by parent id it is quite easy to recursively build the list. This will only require one database query.
<?php
//example data
$items = array(
array('id'=>1, 'title'=>'Home', 'parent_id'=>0),
array('id'=>2, 'title'=>'News', 'parent_id'=>1),
array('id'=>3, 'title'=>'Sub News', 'parent_id'=>2),
array('id'=>4, 'title'=>'Articles', 'parent_id'=>0),
array('id'=>5, 'title'=>'Article', 'parent_id'=>4),
array('id'=>6, 'title'=>'Article2', 'parent_id'=>4)
);
//create new list grouped by parent id
$itemsByParent = array();
foreach ($items as $item) {
if (!isset($itemsByParent[$item['parent_id']])) {
$itemsByParent[$item['parent_id']] = array();
}
$itemsByParent[$item['parent_id']][] = $item;
}
//print list recursively
function printList($items, $parentId = 0) {
echo '<ul>';
foreach ($items[$parentId] as $item) {
echo '<li>';
echo $item['title'];
$curId = $item['id'];
//if there are children
if (!empty($items[$curId])) {
makeList($items, $curId);
}
echo '</li>';
}
echo '</ul>';
}
printList($itemsByParent);
Where is $page coming from? You might have an sql injection vulnerability in your code if you're not escaping it or using a prepared statement.
Also the SELECT statement inside a for loop jumps out as a bad practice. If the table is not that big, then select the contents of the entire table and then iterate through the result set in PHP to build the tree data structure. This could take up to n*(n-1)/2 iterations in the pathological case of your tree being a linked list. Stop when all nodes have been added to the tree, or the number of remaining nodes remains the same from one iteration to the next - this means the remaining nodes are not children of your root node.
Alternatively, if your database supports recursive SQL queries, you can use that, and it will only select the nodes that are children of your parent node. You will still have to build the tree object yourself in PHP. The form of the query would be something like:
WITH temptable(id, title, parent_id) AS (
SELECT id, title, parent_id FROM pages WHERE id = ?
UNION ALL
SELECT a.id, a.title, a.parent_id FROM pages a, temptable t
WHERE t.parent_id = a.id
) SELECT * FROM temptable
Substitute the '?' on the second line with the starting page ID.
The simplest fix would just be, when you are doing the initial select to set $pages (which you don't show), add a WHERE clause like:
WHERE pag_parent = 0
(or IS NULL, depending how you're storing "top level" pages).
That way you won't select all the children initially.
When that table gets large, recursion can get unwieldy. I wrote an blog post about a recursion-less method: http://www.alandelevie.com/2008/07/12/recursion-less-storage-of-hierarchical-data-in-a-relational-database/
Finding top parent, all parents, and all children of a node (enhancements for Tom Haigh's answer):
<?php
//sample data (can be pulled from mysql)
$items = array(
array('id'=>1, 'title'=>'Home', 'parent_id'=>0),
array('id'=>2, 'title'=>'News', 'parent_id'=>1),
array('id'=>3, 'title'=>'Sub News', 'parent_id'=>2),
array('id'=>4, 'title'=>'Articles', 'parent_id'=>0),
array('id'=>5, 'title'=>'Article', 'parent_id'=>4),
array('id'=>6, 'title'=>'Article2', 'parent_id'=>4)
);
//create new list grouped by parent id
$itemsByParent = array();
foreach ($items as $item) {
if (!isset($itemsByParent[$item['parent_id']])) {
$itemsByParent[$item['parent_id']] = array();
}
$itemsByParent[$item['parent_id']][] = $item;
}
//print list recursively
function printList($items, $parentId = 0) {
echo '<ul>';
foreach ($items[$parentId] as $item) {
echo '<li>';
echo $item['title'];
$curId = $item['id'];
//if there are children
if (!empty($items[$curId])) {
printList($items, $curId);
}
echo '</li>';
}
echo '</ul>';
}
printList($itemsByParent);
/***************Extra Functionality 1****************/
function findTopParent($id,$ibp){
foreach($ibp as $parentID=>$children){
foreach($children as $child){
if($child['id']==$id){
if($child['parent_id']!=0){
//echo $child['parent_id'];
return findTopParent($child['parent_id'],$ibp);
}else{ return $child['title'];}
}
}
}
}
$itemID=7;
$TopParent= findTopParent($itemID,$itemsByParent);
/***************Extra Functionality 2****************/
function getAllParents($id,$ibp){ //full path
foreach($ibp as $parentID=>$nodes){
foreach($nodes as $node){
if($node['id']==$id){
if($node['parent_id']!=0){
$a=getAllParents($node['parent_id'],$ibp);
array_push($a,$node['parent_id']);
return $a;
}else{
return array();
}
}
}
}
}
$FullPath= getAllParents(3,$itemsByParent);
print_r($FullPath);
/*
Array
(
[0] => 1
[1] => 2
)
*/
/***************Extra Functionality 3****************/
//this function gets all offspring(subnodes); children, grand children, etc...
function getAllDescendancy($id,$ibp){
if(array_key_exists($id,$ibp)){
$kids=array();
foreach($ibp[$id] as $child){
array_push($kids,$child['id']);
if(array_key_exists($child['id'],$ibp))
$kids=array_merge($kids,getAllDescendancy($child['id'],$ibp));
}
return $kids;
}else{
return array();//supplied $id has no kids
}
}
print_r(getAllDescendancy(1,$itemsByParent));
/*
Array
(
[0] => 2
[1] => 3
)
*/
print_r(getAllDescendancy(4,$itemsByParent));
/*
Array
(
[0] => 5
[1] => 6
)
*/
print_r(getAllDescendancy(0,$itemsByParent));
/*
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
)
*/
?>