使用 SQL、PHP(RSS 样式)根据另一张表的 ID 显示一张表的数据

发布于 2024-12-10 12:59:02 字数 8451 浏览 0 评论 0原文

对于训练有素的人来说,这可能是一个简单的问题,但我已经为此苦恼了太久了。

我有两个数据库表,旨在为浏览器生成 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']) 

不是确切的语法,而是我使用的方法,但仅显示通道而不是项目。中心问题有两个:

  1. SQL 查询:我将如何从数据库中选择数据作为联接?如果是这样,则内部联接类似于此:

    选择 Channel.Id、Channel.Title、Item.Title、Item.Desc、Item.Chan_Id 来自频道 内连接项目 ON Channel.Id=Item.Chan_Id ORDER BY Channel.Id

或者可能使用子查询?

  1. 那么如何从两个表中获取数据并用 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:

  1. 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?

  1. 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) inside while( item query) inside foreach( 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

未蓝澄海的烟 2024-12-17 12:59:02

就我个人而言,我只会进行一个简单的查询,例如

select Channel.Title, Channel.Desc, Channel.Link, Channel.id, Item.Title, Item.Desc,
Item.Link as ItemLink from Item, Channel where Channel.id = Item.Chan_id 
order by Channel.id;

查询,获取所有项目(因为我们谈论的不是很多项目),然后循环遍历它们。如果channel.id与之前的频道ID不同,则执行标头操作。

我不知道你在用这些 sprintfs 做什么,因为你什么也没做,它们只是你可以直接放入查询中的文本字符串。

我会使用类来处理数据库,不是因为在这个例子中你需要它,但这是一个很好的实践,一旦你习惯了它就会成为第二天性。然而,作为一个例子(不一定像我这样做):

    $query = "select Channel.Title as ChanTitle, Channel.Desc as ChanDesc, Channel.Link, Channel.id, Item.Title, Item.Desc, Item.Link as ItemLink from Item, Channel where Channel.id = Item.Chan_id order by Channel.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'];
            print $row['ChanTitle']."<br>";
            print $row['ChanDesc']."<br><br>";
        }
        print $row['Title']."<br>".$row['Desc']."<br><br>";
    }

这样你只需要从数据库中获取一个数据,而不是为每个小类别获取数据,并且只处理数组中的数据。请注意,这会错过任何具有 id 但没有匹配频道的组,但我想这是有道理的。

Personally I would just go for a simple query such as

select Channel.Title, Channel.Desc, Channel.Link, Channel.id, Item.Title, Item.Desc,
Item.Link as ItemLink from Item, Channel where Channel.id = Item.Chan_id 
order by Channel.id;

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):

    $query = "select Channel.Title as ChanTitle, Channel.Desc as ChanDesc, Channel.Link, Channel.id, Item.Title, Item.Desc, Item.Link as ItemLink from Item, Channel where Channel.id = Item.Chan_id order by Channel.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'];
            print $row['ChanTitle']."<br>";
            print $row['ChanDesc']."<br><br>";
        }
        print $row['Title']."<br>".$row['Desc']."<br><br>";
    }

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文