Give back JSON Array with Sub-Arrays - php

My table looks like:
id | title | link | kind
------------------------
1 link1 http one
4 link2 http two
2 link9 http one
I want to give back a JSON Array (JSON parsing is not the problem!) which looks like:
one
- link1, http
- link9, http
two
- link2, http
The kind-colum is dynamic so I do not know the actual string. (But it is never (null)!)
What I have:
$links = array();
while($row = mysql_fetch_object($result)) {
$link = array(
'title' => $row->title,
'link' => $row->link,
'kind' => $row->kind
);
$links[] = $link;
}
echo json_encode($links);
That's one array with all columns for each element.

Use $row->kind as an index into the top level array.
$kinds = array('one' => 1, 'two' => 2, ...etc...);
$links = array();
while($row = mysql_fetch_object($result)) {
$link = array(
'title' => $row->title,
'link' => $row->link
);
$links[$kinds[$row->kind]][] = $link;
}
echo json_encode($links);

You can do this in MySQL query:
SELECT CONCAT("[",
GROUP_CONCAT(
CONCAT("{".kind.":'",title ,"'"),
CONCAT(",".kind.":'",link),"'}")
)
,"]") AS json
FROM table_name;

Related

check if value exist in each array multidimensional array

i hava multidimensional array
<?php
$data = array(
array(
'name'=>'ahmed',
'job'=>'engineer',
'age'=>25,
'hobbies' => array('drawing','swimming','reading'),
'skills' => array('coding','fasting learning','teaching')
),
array(
'name'=>'Sara',
'job'=>'designer',
'age'=>19,
'skills'=>array('fast learning')
) ,
array(
'name'=>'Ali',
'age'=>25,
'city'=>'cairo'
),
array(
'name'=>'Hossam',
'job'=>'accountant',
'age'=>25,
'city'=>'zagazig'
),
array(
'name'=>'Esraa',
'job'=>'Designer',
'age'=>23,
'city'=>'zagazig',
'hobbies' => array('writing','reading'),
'skills' => array('coding','teaching')
),
);
i want count Arrays where city = "zagazig" or "cairo"
and echo Array Values
Example :
There is [ 1 ] people of City => [ cairo ] :
---------------- Result -----------------------
Name => Ali
Age => 25
City => cairo
if City !exist echo Values
Example :
*---------------- Invaild Data -------------
----------------------- First ---------------
Name => Sara
Job => designer
Age => 19
Skill => fast learning
----------------- Second ----------------
Name => ahmed
Job => engineer
Age => 25
-------------------- Hobbies ----------------
drawing
swimming
reading
-------------------- Skills ----------------
coding
fasting learning
teaching
but i don't know how to loop Multidimensional Array
Given that this is just a raw array, a simple if with foreach should suffice.
First, if the criteria is to get certain entries using city, just use a stripos to search;
$search_string = 'zagazig';
$results = array();
foreach($data as $value) {
if(
!empty($value['city']) &&
(stripos($value['city'], $search_string) !== false)
) {
$results[] = $value;
}
}
This checks if the entry has a city index, then just pushes that array inside a container $result. After gathering the results, just loop it like any normal array:
if(!empty($results)) {
echo 'Number of results: ' , count($results), '<br/> Result <hr/>';
foreach($results as $r) {
echo "
Name: {$r['name']}
Job: {$r['job']}
Age: {$r['age']} <br/>
";
echo !empty($r['hobbies']) ? '<br/>Hobbies: <br/>' . implode('<br/>', $r['hobbies']) : '';
}
}
Output
Of course you can use a <table> tag if you want, this is just an ugly example.
If you like something a little bit different, you can also use array_filter:
Here's an example of it (this also includes some searching inside hobbies and skills):
$search_string = 'coding';
$criteria = 'skills';
$results = array_filter($data, function($e) use ($search_string, $criteria) {
return (
!empty($e[$criteria]) &&
(!is_array($e[$criteria])
? (strpos($e[$criteria], $search_string) !== false)
: (in_array($search_string, $e[$criteria]))
)
);
});
Output
Use php foreach() like:
foreach (array_expression as $value)
{
statement
}
Foreach Documentation

retrieving data from two tables into multidimensional array api json response

I am learning Api development where i want to retrieve data from two tables
First table (items) contains:
id, feed_id, title, author, content
Second table (feeds):
feed_id,title,url
I want to get Json response like:
{
- stories :
[
id
feed_id {
title,
url
}
title
author
]
}
My PHP function to retrieve story biased on id is like:
$app->get('/stories/:id', 'authenticate', function($story_id) {
$response = array();
$result = Database::get('db')->table('items')
->eq('rowid', $story_id)
->findOne();
//$response["error"] = false;
if ($result != NULL) {
$response['stories'] = array(
'id' => $result["id"],
'feed_id' => $result["feed_id"],
'title' => $result["title"],
'isBreaking' => $result['isBreaking'],
'author' => $result['author'],
'updated' => $result["updated"],
'url' => $result['url'],
'content' => $result["content"]);
echoRespnse(200, $response);
}
else {
$response["error"] = true;
$response["message"] = "The requested resource doesn't exists";
echoRespnse(404, $response);
}
});
The result i get is like:
{
- "stories": [
{
id
feed_id
title
url
}
]
}
How can i retrieve data from the second tablet (feeds) biased on feed_id and get the data into sub array?
as #MikeBrant mentioned you have to use join between two tables to retrieve correct data. the plain query will be something like this:
select items.id, items.title, items.author, items.content, feeds., feeds.title as feed_title, feeds.url from items left join feeds on items.feed_id = feeds.feed_id
and then change your $response['stories'] like this:
$response['stories'] = array(
'id' => $result["id"],
'feed_id' => array(
'title' => $result["feed_title"],
'url' => $result["url"]
),
'title' => $result["title"],
.
.
.
);
you get the idea :)

php recursive function to built menu

i m trying to build recursive menu using PHP but not succeeding
mysql table
menuid name parentid
and my php code
function generateMenubar()
{
$data = Yii::app()->db->createCommand("select * from menu");
$result = $data->queryAll();
$html = '<ul class = "navigation">';
foreach($result as $row)
{
if($row['parentid'] == "0")
{
$html .= '<li><span>'.$row["menuname"].'</span>';
$menu_id = $row['menuid'];
$html .= $this->generateHTML($result,$menu_id,$html);
}
}
return $html;
}
function generateHTML($result,$menu_id,$html)
{
foreach($result as $row_sub)
{
if($menu_id == $row_sub['parentid'])
{
$html .= '<ul><li><span>'.$row_sub['menuname'].'</span>';
$menu_id = $row_sub['menuid'];
$html .= $this->generateHTML($result,$menu_id,$html);
$html .= '</li>';
}
}
return $html.'</ui>';
}
but this loop is not stopping and generating wrong output. it can have sub levels upto n level. i want to make it dynamic cuz levels may change in future any suggestion ?
Your problem is that you do not have a structured result to iterate over. You might have SubElement 2 > 3 > 4 as your first result but 2 > 3 > 1 as your 5th Result. So you can't just iterate over the result once and build your html.
What you want to do (appart from, switching to nested sets, which is what you REALLY want to do wink) is structure your result first.
Iterate over your result and build a nested array to iterate over recusively to build your HTML. To find "where to put your element" in your recursive array you need to recursively check back with your existing array always as well. IF all you store is id and parent id, how to find out what the root element is before you checked ALL elements right?
So i could write the code to do so, but i rather do not because it would be a horrible solution anyway.
To do so more efficiently it would really help if you do not only store your parentid but a level as well.
Then you could store your elements in a two dimensional array storing all elements for each level and then recursively use that array. i.e.
$navigationTempArray = array();
foreach($fakeMySQLResult as $row)
{
if(!array_key_exists($row['level'], $navigationTempArray )) {
$navigationTempArray[$row['level']] = array();
}
if(!array_key_exists($row['parentid'], $navigationTempArray[$row['level']] )) {
$navigationTempArray[$row['level']][$row['parentid']] = array();
}
$navigationTempArray[$row['level']][$row['parentid']][] = $row;
}
now you have an array like this:
array (
0 => array(
'root' => array(
1 => array('title' => 'Start' ...)
2 => array('title' => 'Team' ...)
3 => array('title' => 'Projects' ...)
)
),
1 => array(
2 => array(
4 => array('title' => 'Development' ...)
5 => array('title' => 'Design' ...)
6 => array('title' => 'Sales' ...)
),
3 => array(
7 => array('title' => 'Mayhem' ...)
8 => array('title' => 'X' ...)
)
),
2 => array(
4 => array(
9 => array('title' => 'PHP' ...)
10 => array('title' => 'MySQL' ...)
)
)
)
Now you can iterate over this array recursively, solving every level for every item to infinity ;-)
function returnSubNavigation($id,$level,$fullNavigationArray) {
$html = '';
if(array_key_exists($level, $fullNavigationArray) && array_key_exists($id, $fullNavigationArray[$level])) {
$html .= '<ul>';
foreach($fullNavigationArray[$level][$id] as $subElement) {
$html .= '<li><span>'.$subElement["menuname"].'</span>';
$html .= returnSubNavigation($subElement['id'], $level+1, $fullNavigationArray);
$html .= '</li>';
}
$html .= '</ul>';
}
return $html;
}
echo returnSubNavigation('root', 0, $navigationTempArray);
Here is an online fiddle kind of thing that proves it works
Some people who do not want to use nested sets often store pathes rather than parent id's.
i.e.:
| id | path |
| 1 | 1 |
| 2 | 2 |
| 3 | 1.1 |
| 4 | 1.2 |
| 5 | 2.1 |
| 6 | 3 |
This is a lot easier (cheaper in terms of performance) to iterate over. You can sort it a lot easier. Still, it brings a lot of problems and restrictions.

How to create a query to get result that using where clause as result array index?

This is the query I use:
$idList="32,33,21,11";
$query = "SELECT post_id, meta_value FROM wp_posts
WHERE meta_key = 'grade' AND post_id IN ($idList)";
As a result, the where clause become keys:
$result = array(
0 => array('post_id'=> 32, 'meta_value'=>5),
1 => array('post_id'=> 33, 'meta_value'=>2),
2 => array('post_id'=> 21, 'meta_value'=>8),
)
I desire to have a result like this:
$result = array(
0 => array( 32 => 5 ),
1 => array( 33 => 2 ),
2 => array( 21 => 8 ),
)
How to achieve this? Thanks!
Loop through the result set like this:
$_final = array(); // new result set
foreach ($result as $value)
$_final[] = array($value['post_id'] => $value['meta_value']);
unset($result); // free memory from old result set
UPDATE: If there are too many element and you afraid of memory consumption, you can do it the following way:
$_final = array(); // new result set
foreach ($result as $key => $value) {
$_final[] = array($value['post_id'] => $value['meta_value']); // composing new data
unset($result[$key]); // unsetting already parsed value
}
unset($result); // freeing memory from old result set

MySQL Select FROM 3 tables AND put that in PHP array

Sorry for bad english and bad title!
I have the table "post"
id title
1 test Thread
2 hello
3 just
so have "tags"
tagid tagname
1 test
2 russia
3 new site
so have a post_tags
tagid postid
1 1
2 1
3 1
I need an array from var_dump next below:
$posts = array(
1 => array(
'title' => 'test Thread',
'tags' => array(
'test', 'russia', 'new site',
),
),
2 => array(
'title' => 'hello',
'tags' => NULL
),
3 => array(
'title' => 'just',
'tags' => NULL
),
)
I trying do it, but i getting not that what i want.
SELECT `post`.`id`, `post`.`title`, `tags`.`tagname` FROM `post`
LEFT JOIN `post_tags` ON `post_tags`.`tagid` = `post`.`id`
LEFT JOIN `tags` ON `post_tags`.`tagid` = `tags`.`tagid`
I getting in SQL next following:
id title tagname
1 test Thread test
1 test Thread russia
1 test Thread newsite
2 hello NULL
3 just NULL
PHP
$query = mysql_query("SELECT `post`.`id`, `post`.`title`, `tags`.`tagname` FROM `post`
LEFT JOIN `post_tags` ON `post_tags`.`tagid` = `post`.`id`
LEFT JOIN `tags` ON `post_tags`.`tagid` = `tags`.`tagid`");
$posts = array();
while ($row = mysql_fetch_assoc($query))
{
$posts[] = $row;
}
var_dump($posts);
Thank you!!!
The query is fine. You just need some logic in your loop:
while ($row = mysql_fetch_assoc($query))
{
if (isset($posts[$row['id']])) {
$posts[$row['id']]['tags'][] = $row['tagname'];
}
else {
$posts[$row['id']] = array(
'title' => $row['title'],
'tags' => $row['tagname'] === null ? null : array($row['tagname'])
);
}
}
If you have already seen a row with the same post id then all you want from the current row is the tag name (so add this to the "tags" array). If it's the first time a row with this post id is seen just add it to $posts, being a little careful to set "tags" to either null or an array with one element.
you cannot get a multi-dimensional arrays back from a mysql database. you must do your own post processing to the results if you want it in that form. Something like this maybe?
$posts = array();
while ($row = mysql_fetch_assoc($query))
{
if (!isset($posts[$row['id']])) {
$posts[$row['id']] = array();
$posts[$row['id']]['title'] = $row['title'];
$posts[$row['id']]['tags'] = array();
}
if ($row['tagname'] != null) $posts[$row['id']]['tags'][] = $row['tagname'];
}
Try this:
while ($row = mysql_fetch_assoc($query))
{
if( !isset( $posts[$row["id"]] ) ) {
$posts[ $row["id"] ] = array( "title" => $row["title"], "tags" => array() );
}
array_push( $posts[ $row["id"] ][ "tags" ], $row["tagname"] );
}
I can't debug it, so tell me if you get any errors

Categories