使用 SQL、PHP(RSS 样式)根据另一张表的 ID 显示一张表的数据
对于训练有素的人来说,这可能是一个简单的问题,但我已经为此苦恼了太久了。
我有两个数据库表,旨在为浏览器生成 RSS 提要:“频道”和“项目”:
**Channel Table** Primary Key: Id
Id Title Desc Link
1 News latest www...
2 Sport latest www...
3 Gossip latest www..
如您所见,有多个数据库表频道,这是我的查询的核心。
**Item Table** Primary Key: Id, Index Key: Chan_Id
Id Title Desc Link Chan_Id
1 Footie Liv-ManU1 www... 2
2 Cricket India-Eng.. www... 2
3 G5 Summit G5 Talks.. www... 1
4 X-Factor Simon Cowell.www... 3
5 Iraq MOD says... www... 1
6 M Jackson Court trial..www... 3
现在我已经看到可以通过 PHP 显示 RSS 提要的脚本,并且效果很好 - 主要问题是我看到的所有示例都假设您只有一个频道可以将您的项目附加到。就
News
G5 Summit G5 Talks......
Iraq MOD says......
我而言有多个频道,我要寻找的是首先打印出具有相关内容的多个频道:
News
G5 Summit G5 Talks......
Iraq MOD says......
Sport
Footie Liv-ManU1.....
Cricket India-Eng.....
Gossip
X-Factor Simon Cowell..
M Jackson Court trial..
然后最终将此数据转储到单独的 xml 文件中,具体取决于主题(Footie.xml、Cricket.xml 等)这部分只需要进行一些微调,因为我有一个使用 PHP DOM 构建和保存的公式:
$doc->save(row['chan_title'])
不是确切的语法,而是我使用的方法,但仅显示通道而不是项目。中心问题有两个:
SQL 查询:我将如何从数据库中选择数据作为联接?如果是这样,则内部联接类似于此:
选择 Channel.Id、Channel.Title、Item.Title、Item.Desc、Item.Chan_Id 来自频道 内连接项目 ON Channel.Id=Item.Chan_Id ORDER BY Channel.Id
或者可能使用子查询?
- 那么如何从两个表中获取数据并用 PHP 显示它呢?将方法包装在类中并这样做会更容易吗?我尝试在
foreach(item)
内的while(item query)
内使用while(channel query)
但只显示通道信息。可能是错误的排列,但我一直在尝试寻找解决方案,但需要一些专家的帮助,以便我可以继续前进!
我们将不胜感激您的帮助,我会尽快回复。
编辑 - 哇,2天了,没有回复,没那么难!!事实上,事实并非如此。我不需要它如此复杂,重点是更多关于正确的语法。仍然没有找到真正的解决方案,但已经接近了 - 我决定使用两个查询,其中有两个 while
语句,一个在另一个语句内:
$detQry = sprintf("SELECT * FROM ".$detailsTable);
$itQry = sprintf("SELECT id, title, description FROM ".$itemsTable." WHERE chan_id = ".$detailsTable.".id ORDER BY chan_id ASC LIMIT 0, 30 ");
$result = mysql_query($detQry) OR die ('Could not execute query: ' . mysql_error());
$run = mysql_query($itQry) OR die ('Could not execute query: ' . mysql_error());
while($row = mysql_fetch_assoc($result)) {
echo $row['title'].'<br>';
echo $row['description'].'<br><br>';
while(list($ttl, $dsc, $pbd) = mysql_fetch_array($run)) {
echo $ttl.'<br>';
echo $dsc.'<br><br>';
echo $pbd.'<br><br><br>';
}
}
问题是,当我运行此脚本时,只有 Channel 'title ' 和 '描述'打印..我不做什么才能使这项工作成功?是否与 list()
语句有关?
欢迎任何帮助来缩短痛苦...
编辑2 - 已解决,感谢伍迪的建议。花了很长时间,但在测试了公式后终于得到了我正在寻找的具体结果伍迪给的。有一些单通道到“n”个项目的脚本,但我需要一个“n”通道到“n”个项目 - 这是完美且灵活的。以我目前的经验水平,需要很长时间才能得出这样的答案 - 再次感谢。
(some db_connect stuff..)
$query = "SELECT *
FROM webref_rss_items, webref_rss_details
WHERE webref_rss_details.id = webref_rss_items.chan_id
ORDER BY webref_rss_details.id";
$t_result = mysql_query( $query ) OR die ('Could not execute query: ' . mysql_error());
$rowCount = mysql_num_rows( $t_result );
$cat = -1; // last category
for($r = 0; $r < $rowCount; $r++)
{
$row = mysql_fetch_array( $t_result );
if($row['id'] != $cat)
{
$cat = $row['id'];
//create doctype
$doc = new DOMDocument('1.0','UTF-8');
header('content-type: text/xml');
//create rss root with values
$root = $doc->createElement('rss');
$root->setAttribute('version', '2.0');
$doc->appendChild($root);
//create channel element
$channel = $doc->createElement("channel");
$root->appendChild($channel);
// add node for each record, create the text nodes for element and add text
$title = $doc->createElement('title', $row['title']);
$channel->appendChild($title);
$link = $doc->createElement('link', $row['link']);
$channel->appendChild($link);
$desc = $doc->createElement('description', $row['description']);
$channel->appendChild($desc);
$lang = $doc->createElement('language', $row['lang']);
$channel->appendChild($lang);
$image = $doc->createElement('image');
$image = $channel->appendChild($image);
$imttl = $doc->createElement('title', $row['image_title']);
$image->appendChild($imttl);
$imlink = $doc->createElement('link', $row['image_link']);
$image->appendChild($imlink);
$imdesc = $doc->createElement('description', $row['image_desc']);
$image->appendChild($imdesc);
$imwidth = $doc->createElement('width', $row['image_width']);
$image->appendChild($imwidth);
$imheight = $doc->createElement('height', $row['image_height']);
$image->appendChild($imheight);
$imurl = $doc->createElement('url', $row['image_url']);
$image->appendChild($imurl);
$manEdit = $doc->createElement('managingEditor', $row['man_edit']);
$channel->appendChild($manEdit);
$webmaster = $doc->createElement('webmaster', $row['webmaster']);
$channel->appendChild($webmaster);
$copyright = $doc->createElement('copyright', $row['copyright']);
$channel->appendChild($copyright);
$pubDate = $doc->createElement('pubDate', $row['ch_pubDate']);
$channel->appendChild($pubDate);
$lastBuild = $doc->createElement('lastBuildDate', $row['lastBuild']);
$channel->appendChild($lastBuild);
$category = $doc->createElement('category', $row['category']);
$channel->appendChild($category);
$generator = $doc->createElement('generator', $row['generator']);
$channel->appendChild($generator);
$docs = $doc->createElement('docs', $row['docs']);
$channel->appendChild($docs);
$cloud = $doc->createElement('cloud', $row['cloud']);
$channel->appendChild($cloud);
$ttl = $doc->createElement('ttl', $row['ttl']);
$channel->appendChild($ttl);
$rating = $doc->createElement('rating', $row['rating']);
$channel->appendChild($rating);
$textInput = $doc->createElement('textInput', $row['textInput']);
$channel->appendChild($textInput);
$skipHours = $doc->createElement('skipHours', $row['skipHours']);
$channel->appendChild($skipHours);
$skipDays = $doc->createElement('skipDays', $row['skipDays']);
$channel->appendChild($skipDays);
}
//Dynamically Generated Items
$item = $doc->createElement('item');
$item = $channel->appendChild($item);
$it_ttl = $doc->createElement('title', $line['title']);
$item->appendChild($it_ttl);
$it_desc = $doc->createElement('description', $line['desc']);
$item->appendChild($it_desc);
$it_link = $doc->createElement('link, $line['link']');
$item->appendChild($it_link);
$it_guid = $doc->createElement('guid', $line['guid']);
$item->appendChild($it_guid);
$it_pubDt = $doc->createElement('pubDate', $line['pubDate']);
$item->appendChild($it_pubDt);
$it_auth = $doc->createElement('author', $line['author']);
$item->appendChild($it_auth);
$it_ctg = $doc->createElement('category', $line['category']);
$item->appendChild($it_ctg);
$it_cmnt = $doc->createElement('comments', $line['comments']);
$item->appendChild($it_cmnt);
$it_encl = $doc->createElement('enclosure', $line['enclosure']);
$item->appendChild($it_encl);
$it_src = $doc->createElement('source', $line['source']);
$item->appendChild($it_src);
$mast = $row['ch_title'];
$saw = explode(" ", $mast);
$chip = $saw[0].'-'.$saw[1]; // saw1-saw2
$beam = "../../feed/".$chip.".xml";
echo 'Wrote: ' . $doc->save($beam) . ' bytes. <br /><br />';
}
}
?>
完美运作!
probably a straightforward to the trained eye but I have agonised over this for too long now..
I have two db tables designed to generate RSS feeds to the browser: 'Channel' and 'Item':
**Channel Table** Primary Key: Id
Id Title Desc Link
1 News latest www...
2 Sport latest www...
3 Gossip latest www..
As you can see there is more than one channel, which is central to my query..
**Item Table** Primary Key: Id, Index Key: Chan_Id
Id Title Desc Link Chan_Id
1 Footie Liv-ManU1 www... 2
2 Cricket India-Eng.. www... 2
3 G5 Summit G5 Talks.. www... 1
4 X-Factor Simon Cowell.www... 3
5 Iraq MOD says... www... 1
6 M Jackson Court trial..www... 3
Now I have seen scripts where an RSS feed can be displayed thru PHP and it works great - the main problem is all examples I have seen assumes you have only One channel to attach your items to..
News
G5 Summit G5 Talks......
Iraq MOD says......
seeing as I have more than one channel, what I am looking for is to first print out multiple channels with related content:
News
G5 Summit G5 Talks......
Iraq MOD says......
Sport
Footie Liv-ManU1.....
Cricket India-Eng.....
Gossip
X-Factor Simon Cowell..
M Jackson Court trial..
then ultimately dump this data into separate xml files, depending on subject matter (Footie.xml, Cricket.xml, etc.) This part just needs a little fine tuning, as I have a formula for this using PHP DOM to construct and save:
$doc->save(row['chan_title'])
not the exact syntax but method I use works, but shows only channels NOT items. The central issue is two-fold:
SQL Query: how would I go about selecting the data from the db, as a join? If so, an Inner Join similar to this:
SELECT Channel.Id, Channel.Title, Item.Title, Item.Desc, Item.Chan_Id
FROM Channel
INNER JOIN Item
ON Channel.Id=Item.Chan_Id
ORDER BY Channel.Id
or maybe use a sub-query?
- How do I then get the data from two tables and display it with PHP? Would it be easier to wrap up methods in classes and do it that way? I've tried to use a
while( channel query)
insidewhile( item query)
insideforeach( item)
but only displayed channel info. Possibly the wrong permutation but I've been experimenting with a view of finding a solution but need some expert help so I can move on!!
Your help will be appreciated, I will try and respond as soon as I can.
EDIT - Wow, 2 days and no response, can't be that hard!! Well actually, it isn't. I didn't need it to be so complicated, the main point was more about the correct syntax. Still not found a true solution but getting close - I decided to use two queries, with two while
statements, one inside the other:
$detQry = sprintf("SELECT * FROM ".$detailsTable);
$itQry = sprintf("SELECT id, title, description FROM ".$itemsTable." WHERE chan_id = ".$detailsTable.".id ORDER BY chan_id ASC LIMIT 0, 30 ");
$result = mysql_query($detQry) OR die ('Could not execute query: ' . mysql_error());
$run = mysql_query($itQry) OR die ('Could not execute query: ' . mysql_error());
while($row = mysql_fetch_assoc($result)) {
echo $row['title'].'<br>';
echo $row['description'].'<br><br>';
while(list($ttl, $dsc, $pbd) = mysql_fetch_array($run)) {
echo $ttl.'<br>';
echo $dsc.'<br><br>';
echo $pbd.'<br><br><br>';
}
}
Problem is, when I run this script only the Channel 'title ' and 'description' print.. what am I not doing to make this work? Could it be to do with the list()
statement?
Any help welcomed to shorten the agony...
EDIT 2 - Resolved, thanks to a suggestion from Woody. It took a long time, but finally got the specific result I was looking for after I tested the formula given by Woody. There are a few One Channel to 'n' Items scripts, but I needed a 'n' Channel to 'n' Items - this is perfect and flexible. With my current level of experience it would've taken a long time to come up with the answer like this - thanks again.
(some db_connect stuff..)
$query = "SELECT *
FROM webref_rss_items, webref_rss_details
WHERE webref_rss_details.id = webref_rss_items.chan_id
ORDER BY webref_rss_details.id";
$t_result = mysql_query( $query ) OR die ('Could not execute query: ' . mysql_error());
$rowCount = mysql_num_rows( $t_result );
$cat = -1; // last category
for($r = 0; $r < $rowCount; $r++)
{
$row = mysql_fetch_array( $t_result );
if($row['id'] != $cat)
{
$cat = $row['id'];
//create doctype
$doc = new DOMDocument('1.0','UTF-8');
header('content-type: text/xml');
//create rss root with values
$root = $doc->createElement('rss');
$root->setAttribute('version', '2.0');
$doc->appendChild($root);
//create channel element
$channel = $doc->createElement("channel");
$root->appendChild($channel);
// add node for each record, create the text nodes for element and add text
$title = $doc->createElement('title', $row['title']);
$channel->appendChild($title);
$link = $doc->createElement('link', $row['link']);
$channel->appendChild($link);
$desc = $doc->createElement('description', $row['description']);
$channel->appendChild($desc);
$lang = $doc->createElement('language', $row['lang']);
$channel->appendChild($lang);
$image = $doc->createElement('image');
$image = $channel->appendChild($image);
$imttl = $doc->createElement('title', $row['image_title']);
$image->appendChild($imttl);
$imlink = $doc->createElement('link', $row['image_link']);
$image->appendChild($imlink);
$imdesc = $doc->createElement('description', $row['image_desc']);
$image->appendChild($imdesc);
$imwidth = $doc->createElement('width', $row['image_width']);
$image->appendChild($imwidth);
$imheight = $doc->createElement('height', $row['image_height']);
$image->appendChild($imheight);
$imurl = $doc->createElement('url', $row['image_url']);
$image->appendChild($imurl);
$manEdit = $doc->createElement('managingEditor', $row['man_edit']);
$channel->appendChild($manEdit);
$webmaster = $doc->createElement('webmaster', $row['webmaster']);
$channel->appendChild($webmaster);
$copyright = $doc->createElement('copyright', $row['copyright']);
$channel->appendChild($copyright);
$pubDate = $doc->createElement('pubDate', $row['ch_pubDate']);
$channel->appendChild($pubDate);
$lastBuild = $doc->createElement('lastBuildDate', $row['lastBuild']);
$channel->appendChild($lastBuild);
$category = $doc->createElement('category', $row['category']);
$channel->appendChild($category);
$generator = $doc->createElement('generator', $row['generator']);
$channel->appendChild($generator);
$docs = $doc->createElement('docs', $row['docs']);
$channel->appendChild($docs);
$cloud = $doc->createElement('cloud', $row['cloud']);
$channel->appendChild($cloud);
$ttl = $doc->createElement('ttl', $row['ttl']);
$channel->appendChild($ttl);
$rating = $doc->createElement('rating', $row['rating']);
$channel->appendChild($rating);
$textInput = $doc->createElement('textInput', $row['textInput']);
$channel->appendChild($textInput);
$skipHours = $doc->createElement('skipHours', $row['skipHours']);
$channel->appendChild($skipHours);
$skipDays = $doc->createElement('skipDays', $row['skipDays']);
$channel->appendChild($skipDays);
}
//Dynamically Generated Items
$item = $doc->createElement('item');
$item = $channel->appendChild($item);
$it_ttl = $doc->createElement('title', $line['title']);
$item->appendChild($it_ttl);
$it_desc = $doc->createElement('description', $line['desc']);
$item->appendChild($it_desc);
$it_link = $doc->createElement('link, $line['link']');
$item->appendChild($it_link);
$it_guid = $doc->createElement('guid', $line['guid']);
$item->appendChild($it_guid);
$it_pubDt = $doc->createElement('pubDate', $line['pubDate']);
$item->appendChild($it_pubDt);
$it_auth = $doc->createElement('author', $line['author']);
$item->appendChild($it_auth);
$it_ctg = $doc->createElement('category', $line['category']);
$item->appendChild($it_ctg);
$it_cmnt = $doc->createElement('comments', $line['comments']);
$item->appendChild($it_cmnt);
$it_encl = $doc->createElement('enclosure', $line['enclosure']);
$item->appendChild($it_encl);
$it_src = $doc->createElement('source', $line['source']);
$item->appendChild($it_src);
$mast = $row['ch_title'];
$saw = explode(" ", $mast);
$chip = $saw[0].'-'.$saw[1]; // saw1-saw2
$beam = "../../feed/".$chip.".xml";
echo 'Wrote: ' . $doc->save($beam) . ' bytes. <br /><br />';
}
}
?>
Works perfectly!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
就我个人而言,我只会进行一个简单的查询,例如
查询,获取所有项目(因为我们谈论的不是很多项目),然后循环遍历它们。如果channel.id与之前的频道ID不同,则执行标头操作。
我不知道你在用这些 sprintfs 做什么,因为你什么也没做,它们只是你可以直接放入查询中的文本字符串。
我会使用类来处理数据库,不是因为在这个例子中你需要它,但这是一个很好的实践,一旦你习惯了它就会成为第二天性。然而,作为一个例子(不一定像我这样做):
这样你只需要从数据库中获取一个数据,而不是为每个小类别获取数据,并且只处理数组中的数据。请注意,这会错过任何具有 id 但没有匹配频道的组,但我想这是有道理的。
Personally I would just go for a simple query such as
as a query, get all the items (as we are talking of not a lot of items), then loop through them. Where channel.id isn't the same as the previous channel ID, do the header thing.
I have no idea what you are doing with those sprintfs, as you are sprintf'ing nothing, they are just text strings you can put straight into the queries.
I would use classes to deal with the database, not because in this example you need it, but it is a good practice to be in, and once you get use to it it becomes second nature. however, as an example (and not necessarily as I would do it):
That way you are only doing the one get from the database, instead of a fetch for each small category, and just working with the data in arrays. Note this would miss out any groups that had an id without a matching channel, but I guess that would make sense.