如何从 Prepared 语句中获取行数据,然后将其与 AJAX() 函数一起使用
Posted
技术标签:
【中文标题】如何从 Prepared 语句中获取行数据,然后将其与 AJAX() 函数一起使用【英文标题】:How do I get the row data from a Prepared statement and then use it with AJAX() function 【发布时间】:2017-11-05 16:10:10 【问题描述】:使用 mysqli,我的代码运行良好,但是当我尝试使用准备好的语句时,为了提高安全性,我无法将值返回给我的 AJAX() 函数。
这是我的 js 代码
function validateCoSigner()
var contractNo = $('#cosigner_reference_number').val();
var firstName = $('#cosigner_firstname').val();
var lastName = $('#cosigner_lastname').val();
$.ajax(
type: 'POST',
url: 'php/retrieve-applicant1-details.php',
// dataType: 'json',
data:
'contractNo': contractNo,
'firstName' : firstName,
'lastName' : lastName
,
success: function(json)
showCoSigner();
console.log(json);
$('#contractID').val(json.contractID);
$('#loanpurpose').val(json.loanpurpose);
$('#applicant1_firstname').val(json.applicant1_firstname);
$('#applicant1_middlename').val(json.applicant1_middlename);
$('#applicant1_surname').val(json.applicant1_surname);
$('#applicant1_dateofbirth').val(json.applicant1_dateofbirth);
,
error: function()
alert ('error2');
);
这是使用 mysqli 函数的retrieve-applicant1-details.php 文件:
<?php
header('Content-Type: application/json');
$conn = mysqli_connect("localhost", "root","","xxx");
$contractno = $_POST['contractNo'];
$firstname = $_POST['firstName'];
$lastname = $_POST['lastName'];
$sql = "SELECT * FROM contract WHERE contractID='$contractno' AND applicant1_firstname='$firstname' AND applicant1_surname='$lastname'";
$query = mysqli_query($conn,$sql);
$num_row = mysqli_num_rows($query);
$row=mysqli_fetch_assoc($query);
if( $num_row == 1 )
$obj = [
'contractID' =>($row['contractID']),
'loanpurpose' =>($row['loanpurpose']),
'applicant1_firstname' =>($row['applicant1_firstname']),
'applicant1_middlename' =>($row['applicant1_middlename']),
'applicant1_surname' =>($row['applicant1_surname']),
'applicant1_dateofbirth' =>($row['applicant1_dateofbirth']),
];
else
echo 'The reference number, firstname and lastname does not match';
exit;
echo json_encode($obj);
?>
如果我使用如下准备好的语句,我无法弄清楚如何正确获取数据,以便我可以将值返回给我的 Ajax 函数,以便它可以显示在我的表单中。
<?php
header('Content-Type: application/json');
$conn = mysqli_connect("localhost", "root","","xxx");
$contractno = $_POST['contractNo']; //not sure if I still need to use mysqli_real_escape_string here.
$firstname = $_POST['firstName'];
$lastname = $_POST['lastName'];
// prepare statement
$stmt = $conn->prepare("SELECT * FROM contract WHERE contractID=? AND applicant1_firstname=? AND applicant1_surname=?");
// bind
$stmt->bind_param("iss", $contractno, $firstname, $lastname);
// execute
$stmt->execute();
if ($stmt->errno)
echo "FAILURE!!! " . $stmt->error;
else echo "Updated $stmt->affected_rows rows";
$row = $stmt->fetchObject();
$obj = (
'contractID' =>($row['contractID']),
'loanpurpose' =>($row['loanpurpose']),
'applicant1_firstname' =>($row['applicant1_firstname']),
'applicant1_middlename' =>($row['applicant1_middlename']),
'applicant1_surname' =>($row['applicant1_surname']),
'applicant1_dateofbirth' =>($row['applicant1_dateofbirth']),
);
echo json_encode($obj);
?>
我是新手。任何建议将不胜感激。
【问题讨论】:
一方面,fetchObject()
是一种 PDO 方法,而您正在使用 mysqli_。
【参考方案1】:
在 MySQLi 中准备语句时,您需要使用 bind_result()
将结果列绑定到变量中,如果您不准备语句,您将使用该变量而不是 $row
数组 (就像你使用 mysqli_fetch_*()
函数一样)。
您绑定的变量数量与所选列的数量相匹配,这一点很重要。这就是我修改您的查询以匹配它的原因。
然后你需要fetch()
结果。实施这些更改后,您的查询应如下所示
$stmt = $conn->prepare("SELECT contractID,
loanpurpose,
applicant1_firstname,
applicant1_middlename,
applicant1_surname,
applicant1_dateofbirth
FROM contract
WHERE contractID=?
AND applicant1_firstname=?
AND applicant1_surname=?");
$stmt->bind_param("iss", $contractno, $firstname, $lastname);
$stmt->execute();
$stmt->bind_result($contractID, $loanpurpose, $applicant1_firstname, $applicant1_middlename, $applicant1_surname, $applicant1_dateofbirth);
if ($stmt->errno)
die("Query failed to execute: " . $stmt->error);
if ($stmt->fetch())
echo json_encode(array("contractID" => $contractID,
"loanpurpose" => $loanpurpose,
"applicant1_firstname" => $applicant1_firstname,
"applicant1_middlename" => $applicant1_middlename,
"applicant1_surname" => $applicant1_surname,
"applicant1_dateofbirth" => $applicant1_dateofbirth));
else
echo "No matching rows returned.";
$stmt->close();
不,您不应该在使用准备好的语句时使用mysqli_real_escape_string()
- 通过转义不需要转义的引号 (IF I use mysqli prepared statements do i need to escape) 会破坏数据。
您可以检查 $stmt->fetch()
是否返回 true,而不是使用 $stmt->num_rows == 1
- 因为您只期望一行,所以您不需要检查数量 - 只是 something 被提取。根据手册,$stmt->fetch()
返回 true
表示成功查询,null
如果没有返回行。
这种方法可能更好的原因是,您可以避免在使用$stmt->num_rows;
之前调用$stmt->store_result();
。这在资源方面更有效,但也节省了一些打字;-)
还请注意,echo "Updated $stmt->affected_rows rows";
在这里使用没有意义,因为您正在运行 SELECT 查询,而不是 UPDATE 查询。如果要查看返回的行数,可以改用$stmt->num_rows;
。
【讨论】:
非常感谢奇瑞尔。不幸的是,这些值仍然没有到达 AJAX() 函数。我是否也需要在我的 js 文件中进行更改? 啊,我明白了。不,Ajax 本来就很好 - 但返回的 json 应该按名称而不是数字来索引 - 因为您使用json.contractID
来访问结果。我会更新答案。
成功了,谢谢!! @Qirel 对于我的学习:如果返回的 json 是按数字索引的,我将如何编写 Ajax 来访问结果?
您可以将其作为数组元素访问,即使它们是使用命名或编号索引定义的。对你来说,因为 AJAX 的结果在 json
变量中,所以它应该是 json[0]
。
感谢您的明确答复!在我的原始 php 文件中,您可能会注意到如果字段不匹配,我会向用户发送一条消息。现在,我尝试使用: if ($stmt->num_rows == 1) 语句,但是当我尝试向用户回显某些内容时似乎总是出错。我认为这是因为我在 AJAX 上苦苦挣扎。抱歉,不知道在你解决了主要问题后我是否可以问更多问题。以上是关于如何从 Prepared 语句中获取行数据,然后将其与 AJAX() 函数一起使用的主要内容,如果未能解决你的问题,请参考以下文章
使用 Prepared Statement,我如何返回插入行的 id?