带有通配符的 MySQLi 准备语句的奇怪结果(程序)

Posted

技术标签:

【中文标题】带有通配符的 MySQLi 准备语句的奇怪结果(程序)【英文标题】:Strange Results from MySQLi Prepared Statement With Wildcard (Procedural) 【发布时间】:2018-07-11 12:56:24 【问题描述】:

这个有点奇怪...我正在使用带有绑定结果的 mysqli 准备语句(包括通配符),但是虽然 SQL 语句在 phpmyadmin 中工作,但我无法让它在 php 文件中正确输出。

谁能发现我做错了什么?

$servername = "XXXX"; $username = "XXXX"; $password = "XXXX"; $dbname = "XXXX";

$conn = new mysqli($servername, $username, $password, $dbname);

if ($conn->connect_error) 
    die("Connection failed: " . $conn->connect_error);


if (!isset($_GET['searchfield'])) 
    $query_string = NULL;
 else 
    $query_string = $_GET['searchfield'];


$stmt = mysqli_prepare($conn, "
SELECT CONTACTS.CONTACTID, CONTACTS.COMPANY, CONTACTS.FORENAME, 
CONTACTS.SURNAME, CONTNOTES.NOTESID, CONTNOTES.NOTESCONTACTID, 
FILEATT.ATTNOTEID, FILEATT.LONGNOTE, FILEATT.CREATEDATE
FROM CONTACTS
INNER JOIN CONTNOTES
   ON CONTACTS.CONTACTID = CONTNOTES.NOTESCONTACTID
INNER JOIN FILEATT
   ON CONTNOTES.NOTESID = FILEATT.ATTNOTEID
WHERE FILEATT.LONGNOTE LIKE CONCAT('%',?,'%')
ORDER BY FILEATT.CREATEDATE ASC
");

mysqli_stmt_bind_param($stmt, "s", $query_string);// bind parameters
mysqli_stmt_execute($stmt);// execute query
mysqli_stmt_bind_result($stmt, $CONTACTID, $COMPANY, $FORENAME, $SURNAME, $NOTESID, $NOTESCONTACTID, $ATTNOTEID, $LONGNOTE, $CREATEDATE);
$rowcount = mysqli_stmt_num_rows($stmt);

if($rowcount > 0)

    while (mysqli_stmt_fetch($stmt)) 

        echo stuff i.e $COMPANY;
    



mysqli_stmt_close($stmt);
mysqli_close ($conn);

首先,我没有得到 $rowcount 的值

其次,如果我注释掉 if($rowcount > 0) 那么它似乎在抛出错误之前循环了 2 行(应该有数百行):

警告:mysqli_stmt_fetch() 期望参数 1 为 mysqli_stmt,在 filename.php 中给出 null

如果我回显一个长注释字段,它只会变成无法识别的乱码。

有什么想法吗?这可能是我错过了一些简单的事情。

【问题讨论】:

我没有看到任何对 mysqli 错误的处理。将此添加到脚本的顶部:mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); @IncredibleHat - 谢谢 - 虽然输出没有区别。 这看起来很奇怪。因为 $stmt 为 null 的原因是,如果 mysqli 崩溃了,错误报告应该抛出一个原因。 如果我理解你的查询正确,你不能像这样连接准备好的参数,你需要这样做:where field` like ?` and ('%'. $foo .'%',) 但是,公平地说,对 OP ...我确实相信奇怪的 LIKE CONCAT 方法仍然有效 ...这只是我从未做过或从未见过的事情看起来很奇怪;) 【参考方案1】:

终于解决了。

这是长文本字段的异常情况。我的 FILEATT.LONGNOTE 字段是长文本,输出只是垃圾,它把页面的其余部分扔掉了。你必须使用 mysqli_stmt_store_result($stmt);执行后。这似乎解决了问题。

见Prepared mysqli select statement on longtext field is coming back empty

【讨论】:

以上是关于带有通配符的 MySQLi 准备语句的奇怪结果(程序)的主要内容,如果未能解决你的问题,请参考以下文章

PHP:带有“select *”的Mysqli准备语句

带有变量的Mysqli准备好的语句列[重复]

PHP mysqli为带有out参数的存储过程准备语句

MySQLi:使用一个准备好的语句插入多行

PHP mysqli - 从准备好的语句返回关联数组

它是 Mysqli 中的错误吗 - 部分结果