首页 文章

PHP mysqli_fetch_assoc没有返回正确的值

提问于
浏览
2

我有一个旧的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
}

版本2:我尝试过的第二件事,它只返回1行:

...same as above until $sql
if($result=mysqli_query($con,$sql))
{
    $row=mysqli_fetch_assoc($result);
    return $row;
}

版本3:或者我试图像这样完全镜像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对象......

LATER EDIT: 好的!找到了有效的解决方案

此外,我玩了数据,选择了一个较小的块,它突然工作 . 从中可以得出:该函数对40行或5行的响应方式不同 . 它与php.ini设置有关吗?或者选择中可能存在非法字符?可能是'Note'列(来自db)的长度对于数组来说太长了吗?

这是代码的工作块,它从数据库中选择一些行,将它们放入一个数组中,然后将该数组放入最后编码为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));

问题是:如何克服有关阵列/非法字符大小的问题(如果是这种情况)?

1 回答

  • 1

    从PHP的角度来看,您的“版本1”似乎是正确的,但您需要实际处理错误 - 无论是在连接时还是在执行查询时 . 这样做会告诉你在查询中你没有错过 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;
    }
    

    参考文献

相关问题