Php 关联数组到字符串的转换问题
首先,在回答问题时,请尽量简单地解释,因为我对php相当陌生。无论如何,我的问题是,我不明白为什么我的关联数组到字符串转换不起作用。我基本上使用的模型与这里描述的相同:向下滚动查看关联数组的示例。无论如何,当我将“Adam”提交到文本框中时,我总是得到以下输出: 注意:未定义索引: 第24行C:\xampp\htdocs\practice\src\fetchigndatausingpdo.php中的queryStr PID=80=8,FirstName=adam,1=adam,LastName=preston,2=preston,Age=17,3=17,和 下面是代码,如果您有任何建议,请通知我,谢谢:)。出于安全原因,$user和$pass也被故意屏蔽Php 关联数组到字符串的转换问题,php,mysql,sql,arrays,pdo,Php,Mysql,Sql,Arrays,Pdo,首先,在回答问题时,请尽量简单地解释,因为我对php相当陌生。无论如何,我的问题是,我不明白为什么我的关联数组到字符串转换不起作用。我基本上使用的模型与这里描述的相同:向下滚动查看关联数组的示例。无论如何,当我将“Adam”提交到文本框中时,我总是得到以下输出: 注意:未定义索引: 第24行C:\xampp\htdocs\practice\src\fetchigndatausingpdo.php中的queryStr PID=80=8,FirstName=adam,1=adam,LastName=
<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();
}
}
?>
如果您只从查询中收到一行,您可以更改
$result=$stmt->fetchAll()
row以使用数据库处理程序的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;
}
}
..
..
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();
}
}
请详细说明这是否是预期效果
关于守则的一些补充意见:
您已经在使用PDO库及其prepare
方法来高效、安全地使用查询。由于您使用的是parameterbinding,因此无需对接收到的数据进行手动清理,因为PDO将为您处理这些数据。这里讨论这一行:
$name = mysql_real_escape_string($_POST['name']);
还有这个:
$stmt->execute(array($name))
您可以将执行部分更改为
$stmt->execute(array($_POST['name']))
相反。此外,使用PDO时检查是否返回任何结果的常规方法是您正在执行的语句的rowCount()
方法。即使查询结果集中没有任何匹配项,PDO也会返回true
。综合以上所有方法,您的代码部分如下所示:
..
foreach($result as $person){
foreach ($person AS $field => $value){
$terms--;
$GLOBALS['queryStr'].= $field.' = '.$value;
if($terms){
$GLOBALS['queryStr'].=' AND ';
}
echo $queryStr;
}
}
..
..
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();
}
}
。。
如果(isset($_POST['name'])){
试一试{
$dbh=newpdo('mysql:host=localhost;dbname=my_db',$user$pass,数组(PDO::ATTR_PERSISTENT=>true));
$stmt=$dbh->prepare(“从名字相似的人中选择*);
$stmt->execute(数组($\u POST['name']);
$resultsSize=$stmt->rowCount();
如果($resultsSize>0){
$queryStr='';
$result=$stmt->fetchAll();
foreach(结果为$person){
$terms=sizeof(数组_键($person));
foreach($person AS$field=>$value){
美元条款--;
$queryStr.=$field.'='.$value;
如果($条款){
$queryStr.='和';
}
$queryStr.='
';//更简单的HTML视觉评估
}
}
echo$queryStr;
}
}捕获(PDO$e){
echo$e->getMessage();
}
}
通过上述重构(首先检查是否设置了$\u POST['name']
),可以避免分配给数据库连接的额外资源(即使您没有使用它)。将您的连接初始化与其他执行的代码放在一起不是问题。在这种情况下,您可以使用一个catch
块来处理错误(在这种情况下,它们的性质类似,或者与数据库的连接有问题)
对查询所做的更改:在比较字符串值时,等号(=)将导致逐字节比较精确值,而LIKE运算符的优点是不会遇到任何编码方面的问题,并且使用LIKE是比较字符串值的通常可接受的方法(同样,使用LIKE可以使用通配符(%
字符等)
**编辑:
我已经根据您的评论更新了上述代码-我还将字符串的输出移动到外部
foreach
循环之后(因此在处理完所有返回的行后将打印)。我已经将您的变量从$GLOBALS
超全局变量更改为局部变量(当前上下文并不意味着您需要在此文件或页面生成之外访问它,如果需要,请研究使用$\u会话变量的可能性)。您可以使用http\u build\u query()来完成此操作。从关联(或索引)会话生成URL编码的查询字符串数组提供。嗨,好的,我已经更改了我的代码,它在我的原始代码区。它几乎和你的完全一样,但是“echo$queryStr”超出了foreach括号。这是因为我的目标是一个结果行,可以很容易地解析以显示firstname、lastname和age的值。我几乎实现了这一点,但结果仍然有点不确定。我编辑了我的主要帖子以显示我当前的结果。我想我们几乎破解了它,只需要再多一点“整理”根据您的评论对代码进行了一些修改,请检查编辑。