PHP mysqli_fetch_assoc 没有返回正确的值

Posted

技术标签:

【中文标题】PHP mysqli_fetch_assoc 没有返回正确的值【英文标题】:PHP mysqli_fetch_assoc not doing returning correct value 【发布时间】:2017-07-29 07:51:30 【问题描述】:

我有一个旧的 php 代码,其中包含 mysql

它从 SELECT 语句中获取一个数组,将其作为属性添加到 JSON 对象中,并回显编码后的 JSON。

我将其更改为使用 mysqli,但是当我尝试获取行并从中创建一个数组时,它什么也不返回。

这是旧的mysql代码:

$con = mysql_connect('host','account','password');
if (!$con)

    //log my error
;

mysql_select_db("database_name", $con);
mysql_set_charset('utf8');
$sql = "SELECT field1 as Field1, field2 as Field2 from table where ID = '".$parameter."'";
$query = mysql_query($sql);
$results = array();
while($row = mysql_fetch_assoc( $query ) )

    $results[] = $row;

return $results;

版本 1:这是我尝试编写的新版本:

$con = mysqli_connect('host','account','password','database_name');
$sql = "SELECT field1 as Field1, field2 as Field2 from table where ID = '".$parameter."'";
$results = array();
if($result=mysqli_query($con, $sql))

    while ($row=mysqli_fetch_assoc($result)) 
    
        $results[] = $row;
    
    return $results;

else

    //error

Version2:我尝试的第二件事,它只返回 1 ROW:

...same as above until $sql
if($result=mysqli_query($con,$sql))

    $row=mysqli_fetch_assoc($result);
    return $row;

Version3:或者我尝试完全镜像mysql结构是这样的:

$sql = "SELECT ...";
$query = mysqli_query($con, $sql);
$results = array();
while($row = mysqli_fetch_assoc( $query ) )

    $results[] = $row;

return $results;

将结果数组包装到 JSON 中:

$obj = new stdClass();
$obj->Data = $results;
$obj->ErrorMessage = '';
die(json_encode($obj)); //or echo json_encode($obj);

mysqli 版本都没有工作,所以我想这些数组的创建方式可能会发生重要变化。

关于第一个 mysqli 示例可能出错的任何提示?

使用 Version2,我可以知道 SQL 连接在那里,并且我至少可以选择一行。但它显然只有一行,而不是返回它。这让我觉得,构建数组是问题的根源,或者它与 JSON 对象有关......

稍后编辑: 好的!找到了一个可行的解决方案。

另外,我玩弄了数据,选择了一个较小的块,它突然起作用了。从中吸取的教训:该函数对 40 行或 5 行的响应方式不同。它与 php.ini 设置有关吗?或者选择中可能有非法字符?可能是“注释”列(来自数据库)的长度太长,数组无法处理?

这是工作代码块,它从数据库中选择一些行,将它们放入一个数组中,然后将该数组放入一个对象中,该对象最后被编码为 JSON,旁边有一个状态消息。可以改进,但这只是为了演示。

$con = mysqli_connect('host','username','password','database_name');
if (!$con)

    $errorMessage = 'SQL connection error: '.$con->connect_error;
    //log or do whatever.
;
$sql = "SELECT Field1 as FieldA, field2 as FieldB, ... from Table where ID='something'";

$results = array();

if($result = mysqli_query($con, $sql))

    while($row = mysqli_fetch_assoc($result))
    
        $results[] = $row;
    

else 

    //log if it failed for some reason
    die();


$obj->Data = $results;
$obj->Error = '';
die(json_encode($obj));

问题是:如何解决有关数组大小/非法字符(如果是这种情况)的问题?

【问题讨论】:

你在哪里定义$con?是否正确连接?你的 SELECT 查询是什么,你知道它有效吗? 嗨! $con 是连接处理程序,当它到达这一点时它正在工作。 SELECT 也可以,因为我尝试将其打印出来,然后将其粘贴到 MYSQL 工作台中,它似乎可以工作。 你的 mysqli_error() 在哪里?你得到什么错误? 目前有太多的未知数。启用错误报告并显示代码的所有相关部分(包括连接、如何使用此代码以及实际查询)。 嗨!我稍微更新了这个问题。我打开了错误报告,这个脚本中有 0 个错误。一切似乎都很好。实际上,在我返回数组之后,我做了一个 print Count($array);就可以了,它会正确显示数字。但是当我将结果数组添加到对象时,它会默默地失败...... 【参考方案1】:

您的“版本 1”从 PHP 的角度来看似乎是正确的,但您需要实际处理错误 - 无论是在连接时还是在执行查询时。这样做会告诉您您实际上并没有查询表,您在查询中缺少FROM tablename

连接时使用mysqli_connect_error(),查询时使用mysqli_error($con) 以获取实际错误。一般的 PHP 错误报告也可能对您有所帮助。

下面的代码假定$parameter 在此代码之前定义。

$con = mysqli_connect('host','account','password','database_name');
if (mysqli_connect_errno())
    die("An error occurred while connecting: ".mysqli_connect_error());

$sql = "SELECT field1 as Field1, field2 as Field2 
        FROM table
        WHERE ID = '".$parameter."'";

$results = array();
if ($result = mysqli_query($con, $sql)) 
    while ($row = mysqli_fetch_assoc($result)) 
        $results[] = $row;
    
    return $results;
 else 
    return mysqli_error($con);

错误报告

添加

error_reporting(E_ALL);
ini_set("display_errors", 1);

在文件的顶部,直接在<?php 之后可以让您获得 PHP 错误。

注意:错误不应该显示在实时环境中,因为它可能会被其他人利用。在开发过程中,它很方便并且可以简化故障排除 - 但它不应该以其他方式显示。

安全

您还应该注意,此代码容易受到 SQL 注入的影响,您应该使用带占位符的参数化查询来保护自己免受这种情况的影响。使用准备好的语句,您的代码将如下所示:

$con = mysqli_connect('host','account','password','database_name');
if (mysqli_connect_errno())
    die("An error occurred while connecting: ".mysqli_connect_error())

$results = array();

if ($stmt = mysqli_prepare("SELECT field1 as Field1, field2 as Field2 
                            FROM table
                            WHERE ID = ?")) 
    if (mysqli_stmt_bind_param($stmt, "s", $parameter)) 
        /* "s" indicates that the first placeholder and $parameter is a string */
        /* If it's an integer, use "i" instead */
        if (mysqli_stmt_execute($stmt)) 
            if (mysqli_stmt_bind_result($stmt, $field1, $field2) 
                while (mysqli_stmt_fetch($stmt)) 
                    /* Use $field1 and $field2 here */
                
                /* Done getting the data, you can now return */
                return true;
             else 
                error_log("bind_result failed: ".mysqli_stmt_error($stmt));
                return false;
            
         else 
            error_log("execute failed: ".mysqli_stmt_error($stmt));
            return false;
        
     else 
        error_log("bind_param failed: ".mysqli_stmt_error($stmt));
        return false;
    
 else 
    error_log("prepare failed: ".mysqli_stmt_error($stmt));
    return false;

参考文献

http://php.net/mysqli.prepare How can I prevent SQL injection in PHP?

【讨论】:

以上是关于PHP mysqli_fetch_assoc 没有返回正确的值的主要内容,如果未能解决你的问题,请参考以下文章

php???mysqli_fetch_assoc()???mysqli_fetch_row()?????????

对象中的mysqli_fetch_assoc

mysqli_fetch_assoc (& PDO fetch assoc) 将数字存储为字符串

mysqli_fetch_assoc() 期望参数/调用成员函数 bind_param() 错误。如何获得实际的mysql错误并修复它?

mysqli_fetch_assoc() 期望参数/调用成员函数 bind_param() 错误。如何获得实际的mysql错误并修复它?

mysqli_fetch_assoc() 期望参数/调用成员函数 bind_param() 错误。如何获得实际的mysql错误并修复它?