【问题标题】:associative array to string conversion issue关联数组到字符串的转换问题
【发布时间】:2014-09-03 10:16:29
【问题描述】:

首先回答时请尝试并尽可能简单地解释,因为我对php相当陌生。无论如何,我的问题是我不明白为什么我的关联数组到字符串的转换不起作用。我基本上使用与此处所述相同的模型:PHP 5 arrays 向下滚动以查看关联数组的示例。无论如何,当我将“亚当”提交到文本框中时,我总是得到的输出是:

注意:未定义的索引: 第 24 行 C:\xampp\htdocs\practice\src\fetchigndatausingpdo.php 中的 queryStr PID = 80 = 8 AND FirstName = adam AND 1 = adam AND LastName = preston AND 2 = preston AND Age = 17 AND 3 = 17 AND

以下是代码,如果您有任何建议,请通知我,谢谢 :)。出于安全原因,还故意将 $user 和 $pass 设为空白。

 <form action="fetchigndatausingpdo.php" method="post">
<input type="text" name="name">
<input type="submit" name="submit" value="submit">
</form>

<?php

$user = "adam";
$pass = "**********";


if(isset($_POST['name'])){
    try{
        $dbh = new PDO('mysql:host=localhost;dbname=my_db', $user, $pass, array(PDO::ATTR_PERSISTENT=>true));

        $stmt = $dbh->prepare("SELECT * FROM persons WHERE FirstName LIKE ?");
        $stmt->execute(array($_POST['name']));
        if($stmt->rowCount() > 0){
            $result = $stmt->fetchAll();
            $terms = count($result);    
            foreach($result as $person){
                foreach ($person AS $field => $value){
                $terms--;
                $GLOBALS['queryStr'].= $field.' = '.$value;
                if($terms){
                    $GLOBALS['queryStr'].=' AND ';
                }
               }        
            }
            echo $queryStr;
        }

    }catch(PDOException $e){
    echo $e->getMessage();
}
}

?>

【问题讨论】:

标签: php mysql sql arrays pdo


【解决方案1】:

如果您只从查询中收到一行,您可以更改您的$result = $stmt-&gt;fetchAll(); 行以使用数据库处理程序的fetch() 方法。这将为您的$result 变量提供一个数组。这样一来,您就不必再做任何更改了。

需要更改,因为fetchAll() 会将数组放入您的$result 变量中(即使只有一个结果)。如果您不将fetchAll() 更改为fetch(),那么您可以尝试将foreach($result as $field =&gt; $value){ 及以下部分更改为以下内容:

..
foreach($result as $person){
    foreach ($person AS $field => $value){
         $terms--;
        $GLOBALS['queryStr'].= $field.' = '.$value;
        if($terms){
            $GLOBALS['queryStr'].=' AND ';
        }
        echo $queryStr;
    }        
}
..

请详细说明这是否是预期的效果。

代码上的一些额外的cmets:

您已经在使用 PDO 库及其prepare 方法来高效、安全地使用查询。当您使用参数绑定时,无需手动清理接收到的数据,因为 PDO 会为您处理。在这里谈论这一行:

$name = mysql_real_escape_string($_POST['name']);

还有这个:

$stmt->execute(array($name))

您可以将执行部分更改为

$stmt->execute(array($_POST['name']))

相反。此外,在使用 PDO 时检查是否返回任何结果的常规方法是您正在执行的语句的 rowCount() 方法。即使您的查询结果集中没有任何匹配项,PDO 也会返回 true。综上所述,您的代码将如下所示:

..

if(isset($_POST['name'])){
    try{
        $dbh = new PDO('mysql:host=localhost;dbname=my_db', $user, $pass, array(PDO::ATTR_PERSISTENT=>true));

        $stmt = $dbh->prepare("SELECT * FROM persons WHERE FirstName LIKE ?");
        $stmt->execute(array($_POST['name']));
        $resultsSize = $stmt->rowCount();
        if($resultsSize > 0){
            $queryStr = '';

            $result = $stmt->fetchAll();
            foreach($result as $person){
                $terms  = sizeof(array_keys($person));    
                foreach ($person AS $field => $value){
                    $terms--;
                    $queryStr .= $field.' = '.$value;
                    if($terms){
                        $queryStr .=' AND ';
                    }
                $queryStr .= '<br/>'; // easier HTML visual evaluation
               }        
            }
            echo $queryStr;
        }

    }catch(PDOException $e){
        echo $e->getMessage();
    }
}

通过上述重构(您首先检查是否设置了$_POST['name']),您可以避免分配给数据库连接的额外资源(即使您没有使用它)。在这种情况下,将连接初始化与其他执行的代码放在一起不是问题,您可以使用一个 catch 块来处理您的错误(因为在这种情况下,它们的性质相似,要么是与数据库的连接有问题。

对查询所做的更改:比较字符串值时,等号 (=) 将导致逐字节比较精确值,而 LIKE 运算符的优点是不会绊倒任何编码花哨 -并且使用 LIKE 是比较字符串值的通常接受的方式(此外,使用 LIKE 您可以使用通配符(% 字符等)。

**编辑

我已经根据您的评论更新了上面的代码 - 我还在外部 foreach 循环之后移动了字符串的输出(因此它会在处理完所有返回的行后打印)。我已将您的变量从 $GLOBALS 超全局变量更改为本地变量(当前上下文并不意味着您需要在此文件或页面生成之外访问它,如果是这样,请研究使用 $_SESSION 变量的可能性)。

【讨论】:

  • 嗨,好的,我已经更改了我的代码,该代码位于我的原始代码区域。它与您的几乎完全相同,但是“echo $queryStr”超出了 foreach 括号。这是因为我要实现的目标是一个可以轻松解析以显示名字、姓氏和年龄的值的结果行。我几乎已经做到了,但是结果仍然有点不确定。我编辑了我的主要帖子以显示我当前的结果。我认为我们几乎已经破解它只是需要多一点“整理”
  • 根据您的评论对代码进行了一些修改,检查编辑。
猜你喜欢
  • 2018-01-12
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
  • 1970-01-01
  • 1970-01-01
  • 2017-11-28
  • 1970-01-01
  • 2019-06-26
相关资源
最近更新 更多