【问题标题】:PDO's fetchAll() method returns half of the columns the query requests. No exception thrownPDO 的 fetchAll() 方法返回查询请求的一半列。没有抛出异常
【发布时间】:2018-01-20 06:25:15
【问题描述】:

这适用于 Apache 2.2.23、PHP 7 和 MySQL 5.6.32。托管环境是 Bluehost 共享托管 Web 服务器。

这里是数据库连接函数:

function connectBlogDatabase() {
$server = 'localhost';
$dbname = 'database_name';
$username = 'database_user';
$password = '1234';
$dsn = 'mysql:host=' . $server . ';dbname=' . $dbname;
$options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
try {
    $link = new PDO($dsn, $username, $password, $options);
} catch (Exception $ex) {
    $_SESSION['error'] .= $ex;
}
return $link;
}

这里是查询函数:

function getMostRecentArticles(int $quantity){
$connection = connectBlogDatabase();
try{
    $sql = "SELECT blog_title, blog_body, blog_description, blog_date FROM blog WHERE published = 1 ORDER BY blog_id DESC LIMIT :quantity;";
    $stmt = $connection->prepare($sql);
    $stmt->bindParam(':quantity', $quantity, PDO::PARAM_INT);
    $stmt->execute();
    $blogs = $stmt->fetchAll();
    $stmt->closeCursor();
    return $blogs;
} catch (Exception $ex) {
    echo $ex;
    $_SESSION['error'] .= "ERROR: Caught Exception \$ex";
    return FALSE;
}
}

查询函数用在下面的显示函数中。这只是为了显示 n 个最近发布的博客文章链接,同时交替 css background-color 属性:

function blog_article_links($quantity){
//get a list of the $quantity most recently written blog articles
$articles = getMostRecentArticles($quantity);
$i = 1;
do{
    if($i % 2 === 0){
        //even numbered blog post
        echo "<li class='blog-nav-li flex-box-blog-link background-
1'>";
    } else{
        echo "<li class='blog-nav-li flex-box-blog-link background-
2'>";
    }
    echo "<a class='nav-article-link' 
href='view/blog_template.php'>";
    echo "<h4 class='nav-article-header'>" . $articles['blog_title'] 
. "</h4>";
    echo "<p class='nav-article-description'>" . 
$articles['blog_description'] . "</p>";
    echo "<footer class='article-footer'>";
    echo "<div class='article-footer-social'>";
    echo "<a class='twitter-share-button tweet' 
href='https://twitter.com/intent/tweet'>Tweet</a>";
    echo "</div><!-- facebook share button-->";
    echo "<div class='fb-share-button fb-share' data-
href='https://developers.facebook.com/docs/plugins/' data-
layout='button' data-size='small' data-mobile-iframe='true'><a 
class='fb-xfbml-parse-ignore' target='_blank' 
href='https://www.facebook.com/sharer/sharer.php
u=https%3A%2F%2Fdevelopers.facebook
.com%2Fdocs%2Fplugins%2F&amp;src=sdkpr
eparse'>Share</a></div>";
    echo "<time datetime='".$articles["blog_date"] . "' 
class='article-footer-date'>" . $articles['blog_date'] . "</time>";
    echo "</footer></a></li>";
    $i += 1;
}while($i <= $quantity);
}

当我运行 blog_article_links() 函数时,没有抛出错误,也没有显示 $ex。当我在 blog_article_links() 中使用 var_dump() 时,我得到以下信息:

" ["blog_description"]=> string(46) "Lorem Ipsum Delta Theda Alpha Omega Pizza Pie." [2]=> string(46) "Lorem Ipsum Delta Theda Alpha Omega Pizza Pie." ["blog_date"]=> string(10) "2017-08-10" [3]=> string(10) "2017-08-10" } }

我在 fetchAll() 方法中使用了各种不同的参数,包括 PDO::FETCH_NUM,显式使用默认 PDO::FETCH_BOTH,甚至曾经为了它而使用 PDO::FETCH_ASSOC,看看是什么会改变。

这些都没有产生我需要的结果。我认为这与

有关
FROM blog WHERE published = 1 ORDER BY blog_id DESC LIMIT :quantity;

查询的一部分。我认为 PDO 搞砸了,因为 PDO 不知道如何处理 ORDER BY 和 DESC LIMIT 关键字。

现在我知道 connectBlogDatabase() 函数有效。还有另一个查询函数使用相同的 connectBlogDatabase() 函数对其 PDO 对象,并且该函数返回预期的结果。

另外,connectBlogDatabase() 使用的数据库用户只有 SELECT、INSERT、UPDATE 和 DELETE 权限。

【问题讨论】:

  • 所以echo '&lt;pre&gt;'.print_r($blogs, true).'&lt;/pre&gt;'; 缺少东西?
  • 仅供参考,$ex 将是一个对象,而不是一个字符串。要从 Exception 对象获取错误消息,请执行 $ex-&gt;getMessage();
  • @PatrickQ 仅回显对象仍会回显3v4l.org/DqNYU
  • 避免在您的 PDO 查询中输入 ;。这仅在 MySQL 命令行上是必需的,它需要知道查询的结束位置。
  • blog_article_links 函数中的 $articles['blog_title'] 等看起来不应该工作。 $articles 是一个行数组,不是单行,对吧?

标签: php mysql pdo


【解决方案1】:

我想出了如何让它正确,但我仍然不知道为什么它首先会出错。

我只有 2 篇博客文章存储在数据库中。我插入了第三篇博客文章并刷新了网页。有效。

这就是我所要做的,但这仍然不能解释它之前没有出现在浏览器中的开发者视图中的事实。

【讨论】:

    【解决方案2】:

    当您在 blog_article_links 函数中调用 $articles = getMostRecentArticles($quantity); 时,$articles 会获取该函数中 $stmt-&gt;fetchAll(); 表达式的值。

    $articles 将是一个多维数组,其中每个内部数组都是查询结果中的一行。因此,当您执行$articles['blog_title']$articles['blog_description'] 等时,这些都是未定义的索引。

    有不同的方法来解决这个问题。一种方法是将您的 blog_article_links 函数分成两个函数,一个打印一篇文章,另一个迭代从数据库返回的列表并为每个函数调用单个输出函数。

    用一个函数获取列表并输出

    function blog_article_links($quantity) {
        //get a list of the $quantity most recently written blog articles
        $articles = getMostRecentArticles($quantity);
        $i = 1;
        foreach ($articles as $article) {
            if ($i % 2 === 0){
                //even numbered blog post
                echo "<li class='blog-nav-li flex-box-blog-link background-1'>";
            } else {
                echo "<li class='blog-nav-li flex-box-blog-link background-2'>";
            }
            blog_article_link($article);
            echo "</li>";
            $i += 1;
        }
    }
    

    辅助函数格式化并输出一篇文章

    function blog_article_link($article) {
        echo "<a class='nav-article-link' href='view/blog_template.php'>
              <h4 class='nav-article-header'>$article[blog_title]</h4>
              <p class='nav-article-description'>$article[blog_description]</p>
              <footer class='article-footer'>
                  <div class='article-footer-social'>
                      <a class='twitter-share-button tweet' href='https://twitter.com/intent/tweet'>Tweet</a>
                   </div>
                   <!-- facebook share button-->
                   <div class='fb-share-button fb-share' data-href='https://developers.facebook.com/docs/plugins/' data-layout='button' data-size='small' data-mobile-iframe='true'>
                       <a class='fb-xfbml-parse-ignore' target='_blank' href='https://www.facebook.com/sharer/sharer.php u=https%3A%2F%2Fdevelopers.facebook.com%2Fdocs%2Fplugins%2F&amp;src=sdkpreparse'>
                           Share
                       </a>
                   </div>
                   <time datetime='$article[blog_date]' class='article-footer-date'>
                       $article[blog_date]
                   </time>
               </footer>
           </a>";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-12
      • 2016-09-15
      • 1970-01-01
      • 2015-09-30
      • 1970-01-01
      相关资源
      最近更新 更多