在 PHP 中,为啥 mysqli_num_rows 不为返回行数为 0 的查询返回整数?
Posted
技术标签:
【中文标题】在 PHP 中,为啥 mysqli_num_rows 不为返回行数为 0 的查询返回整数?【英文标题】:In PHP, why doesn't mysqli_num_rows return an integer for a query with 0 returned rows?在 PHP 中,为什么 mysqli_num_rows 不为返回行数为 0 的查询返回整数? 【发布时间】:2019-03-03 23:59:05 【问题描述】:我对 mysqli_num_rows 有一个奇怪的问题。在搜索这个问题时,我只发现有人遇到无论如何都会返回 NULL 的问题。我还检查了official documentation 的函数,它说它返回查询返回的行数的整数。每当我的查询返回 1 行(它永远不应该返回更多)时,它的行为都符合我的预期。当查询返回 0 行时,我希望函数返回 0,但它返回 NULL。为什么不返回 0?
我知道我的数据库连接良好并且我的查询工作正常,因为当我在数据库中查找记录时,我得到一个整数。我只是不明白为什么返回 NULL 而不是 0。
function getArtistID($name)
global $conn;
$query = "SELECT artist_id FROM artist WHERE artist_name LIKE '$name'";
$result = mysqli_query($conn, $query);
if ($result->num_rows)
$row = mysqli_fetch_assoc($result);
return $row['artist_id'];
else
return 0;
【问题讨论】:
你怎么知道的?鉴于此代码,无论它返回0
还是 null
的行为应该是相同的。我有一种感觉,mysqli_query
是返回 null 的那个,而不是 mysqli_num_rows
。
不要使用global
。如果您的代码需要,这清楚地表明设计不佳。
@tkausl 是的,这是真的。但我很好奇为什么它不返回 0。文档没有提到它返回 NULL。
我真的相信您误解了某些信息。如果它真的返回null,请说明你是如何得出这个结论的,包括任何带有var_dump
s的代码和相应的输出。
人们常说使用global
不好,因为它很难编写单元测试。如果函数引用全局变量,则不能在有限范围内测试函数。为全局变量创建模拟对象很尴尬。见phpunit.readthedocs.io/en/8.0/fixtures.html#global-state
【参考方案1】:
这是我用来重现 num_rows
似乎为 NULL 的情况的一些代码:
<?php
error_reporting(E_ALL);
$conn = new mysqli('127.0.0.1', 'root', null, 'test');
$sql = "SELECT * FROM dual";
$result = $conn->query($sql);
if ($result === false)
print "Error: $conn->error\n";
$n = $result->num_rows;
echo "Dump the num_rows property: ";
var_dump($n);
输出:
Error: No tables used
Notice: Trying to get property of non-object in /Users/bkarwin/Documents/SO/my.php on line 14
Dump the num_rows property: NULL
该通知是因为访问不是对象的变量的面向对象的属性是无效的。这对于 PHP 开发人员来说是一个常见的混淆源,它是 PHP 是一种松散类型语言这一事实的副产品,像 query()
这样的函数可以返回 结果对象或布尔标量.
query()
函数实际上返回了一个 false 作为$result
因为一些错误。在我的代码中,我检查了这个错误,而你没有。
当您运行mysqli::query()
或mysqli::prepare()
或mysqli_stmt::execute()
时,您必须每次检查错误情况。
关于您的查询的某些内容导致了错误。由您来检查错误并报告它。
更新:我编辑了上面的一些文本以使解释更好,但这可能会使下面的一些 cmets 显得格格不入。
【讨论】:
好的,我会添加支票。但是当我在 phpmyadmin 中运行查询时,我没有收到任何错误。我也,当它返回行时不会有任何奇怪的行为。我的表确实有列。我不太明白你的意思。 我的查询只是生成错误的查询示例之一。我是说您的查询可能会产生一些不同的错误。关键是您没有检查错误。 我猜你也没有调用error_reporting()
来启用通知,当$result
是布尔值false 时你应该调用$result->num_rows
。除非它是一个对象,否则您不能从变量请求面向对象的属性。当变量是标量时,您应该在正确配置错误报告级别时收到通知。这在我的代码示例中显示。
当你不配置 PHP 输出通知,并且你不自己检查错误时,你会得到很多令人困惑的效果,因为你不知道什么时候发生了错误。
PHP 开发者学习phptherightway.com 并实践所有建议应该是必读。【参考方案2】:
我只是想不通为什么返回 NULL 而不是 0。
看不到日志输出,我们只能猜测;但是,返回值很可能是 null,因为它引发了错误。
在尝试使用返回值之前,您需要确保在调用函数时处理了错误。
【讨论】:
以上是关于在 PHP 中,为啥 mysqli_num_rows 不为返回行数为 0 的查询返回整数?的主要内容,如果未能解决你的问题,请参考以下文章
php显示报错: Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given
PHP操作数据库出现错误:mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in
mysqli_num_rows() 期望参数通过同一页面上的较早查询有效
INSERT 查询产生“警告:mysqli_num_rows() 期望参数 1 为 mysqli_result,给定布尔值”
警告:mysqli_num_rows() 期望参数 1 为 mysqli_result,bool 给定...我该怎么办? [复制]