【问题标题】:php unsuccessful while loop within prepared statementsphp在准备好的语句中循环失败
【发布时间】:2013-04-22 19:34:37
【问题描述】:

下面的代码是我的sitemap.xml 文件的一部分。我的目标是写出我批准文章的最后修改日期。该数据有两种可能性。

  1. 如果文章没有批准的评论,那么lastmod是批准 文章的日期。
  2. 如果文章至少有 1 条已获批准的评论,则 lastmod 是 最后批准评论的批准日期。

我的输出中的错误是:

  1. 我的数据库中有一些文章没有cmets,但这些无评论文章获得了其他一些文章最后评论的批准日期。结果因为我有一些今天被批准的cmets,所有那些无评论文章的lastmode都是今天的日期。但是这些文章已经很老了。
  2. $newsql 在我的第二个 while 循环中打印 "newstmt prepare error" 屏幕,所以if ($newstmt = $connection->prepare($newsql)) 部分不起作用

你能纠正我吗?

谢谢你,最好的问候

代码

<?php       
//if spesific article is approved then its last modification date = approval date of article
//if spesific article has approved comment(s), then modification date = approval date of its last comment
$sql = "SELECT col_author, col_title, col_approvaldate FROM articles WHERE col_status = ? ORDER by col_approvaldate DESC";

if ($stmt = $connection->prepare($sql)) 
{
    /* bind parameters */
    $stmt -> bind_param("s", $bindparam1);
    
    /* assign value */
    $bindparam1 = 'approved';
    
    /* execute statement */
    $stmt->execute();

    /* bind result variables */
    $stmt->bind_result($author, $title, $articledate);

    /* fetch values */
    while ($stmt->fetch()) 
    {
        //if exist, get approved newest comment approval date
        $newsql = "SELECT col_approvaldate FROM comments WHERE col_status = ? AND col_for_author = ? AND col_for_title = ? ORDER by col_approvaldate DESC LIMIT 1";
        if ($newstmt = $connection->prepare($newsql))
        {
            /* bind parameters */
            $newstmt -> bind_param("sss", $ybindparam1, $ybindparam2, $ybindparam3);
            
            /* give values */
            $ybindparam1 = 'approved';
            $ybindparam2 = $author;
            $ybindparam3 = $title;
            
            /* execute statement */
            $newstmt->execute();

            /* bind result variables */
            $newstmt->bind_result($commentdate);
            
            /* fetch values */
            $biggerdate = '';
            
            while ($newstmt->fetch())
            {                   
                // is there any approved comment for this article?
                if (!is_null($commentdate))
                {$biggerdate = $commentdate;}
            }
            /* close statement */
            $newstmt->close();                  
        }
        else {echo 'newstmt prepare error';}
        
        //print the result
        echo '<url>'."\r\n";
        echo "\t".'<loc>'.root_folder.urlencode('articles').'/'.urlencode(space_to_dash($author)).'/'.urlencode(space_to_dash(no_punctuation($title))).'</loc>'."\r\n";             
        //if there is no approved comment for this article
        if ($biggerdate == '') 
        {
            $biggerdate = $articledate;
        }
        $datetime = new DateTime($biggerdate);
        $biggerdate = $datetime->format('Y-m-d\TH:i:sP');
        echo "\t".'<lastmod>'.$biggerdate.'</lastmod>'."\r\n";
        echo '</url>'."\r\n";

    }
    /* close statement */
    $stmt->close();
    
}
?>

【问题讨论】:

  • SELECT col_approvaldate FROM cmets WHERE col_status = 什么?和 col_for_author = ?和 col_for_title = ? ORDER by col_approvaldate DESC LIMIT 1 在直接执行到数据库时给你(如 phpMyAdmin 或类似)
  • 嘿,您不是使用文章 ID 将 cmets 链接到文章吗?真的吗?
  • @bestprogrammerintheworld 它给了我语法错误。我完全按照你写的尝试了,但我不习惯直接使用 phpmyadmin 查询窗口。
  • @YourCommonSense 是的,可能这是愚蠢的方式,但我不使用 id。
  • 打印$connection-&gt;error以及newstmt prepare error消息,查看错误原因。

标签: php while-loop prepared-statement prepare


【解决方案1】:

应该是这样的

  1. 您必须使用单个查询来获取数据。
  2. 评论必须使用文章 ID 链接
  3. 应该使用PDO 而不是 mysqli

所以,给你:

$sql = "SELECT author, title, a.approvaldate, max(c.approvdate) biggerdate
        FROM articles a
        LEFT JOIN comments c ON c.article_id = a.id AND c.status='approved'
        WHERE a.status = 'approved' 
        GROUP BY a.id
        ORDER BY a.approvaldate DESC";
$stmt = $con->prepare($sql);
$stmt->execute();
$data = $stmt->fetchall();
foreach ($data as $row) {
    extract($row);
    echo "<url>\r\n";
    echo "\t<loc>".root_folder.'articles';
    echo '/'.urlencode(space_to_dash($author));
    echo '/'.urlencode(space_to_dash(no_punctuation($title)))."</loc>\r\n";
    //if there is no approved comment for this article
    if (!$biggerdate) 
    {
        $biggerdate = $approvaldate;
    }
    $datetime = new DateTime($biggerdate);
    $biggerdate = $datetime->format('Y-m-d\TH:i:sP');
    echo "\t<lastmod>$biggerdate</lastmod>\r\n";
    echo "</url>\r\n";
}

它当然没有经过测试,显然包含许多错误,只是为了向您展示一个想法。

首先你必须使查询工作。
然后读取链接的 PDO 标签 wiki 并建立连接。
然后修复所有错误和拼写错误(如果有)

【讨论】:

  • 我会按照你说的方式研究它。但是我想问一下,我的 cmets 表中没有文章 id 作为外键;那么这是否意味着即使 100% 正确,我也无法使用您的代码?
  • 您只需要在articles 表中有一个article id 并在cmets 表中有相应的article id。就是这样
猜你喜欢
  • 2023-03-29
  • 2018-02-21
  • 1970-01-01
  • 2011-07-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 2012-07-07
相关资源
最近更新 更多