首先请回答时请尽可能简单地解释,因为我对php很新。无论如何我的问题是我不明白为什么我的关联数组到字符串转换不起作用。我基本上使用的是与此处描述的模型相同的模型:PHP 5 arrays向下滚动以查看关联数组的示例。无论如何,当我将“Adam”提交到文本框中时,我总是得到的输出是:
注意:未定义的索引: 第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年龄= 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();
}
}
?>
答案 0 :(得分:0)
如果您只从查询中收到一行,则可以更改$result = $stmt->fetchAll();
行以改为使用数据库处理程序的fetch()
方法。这将为您的$result
变量提供一个数组。这样,您就不必进行任何进一步的更改。
需要进行更改,因为fetchAll()
会将数组放入$result
变量中(即使只有一个结果)。如果您不将fetchAll()
更改为fetch()
,那么您可以尝试将foreach($result as $field => $value){
及以下部分更改为以下内容:
..
foreach($result as $person){
foreach ($person AS $field => $value){
$terms--;
$GLOBALS['queryStr'].= $field.' = '.$value;
if($terms){
$GLOBALS['queryStr'].=' AND ';
}
echo $queryStr;
}
}
..
请详细说明这是否是所需效果。
对代码的一些额外评论:
您已经在使用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变量)。