Php mysql_num_rows()希望参数1是资源,在检查成功后给出布尔值

Php mysql_num_rows()希望参数1是资源,在检查成功后给出布尔值,php,mysql,stored-procedures,Php,Mysql,Stored Procedures,我遇到了“mysql\u num\u rows()期望参数1是资源,给定布尔值”的问题 我意识到这意味着查询失败了。但是,我首先要做一个检查,看看查询是否成功,如果成功,我就会得到这个错误。如果查询失败,我不知道为什么我会首先进入if??我还尝试了回显查询并粘贴到phpmyadmin中,它成功运行了 代码如下: $checkloginEmp = "CALL login('".$Email."','".$Password."', '".$NotificationID."', '".$Token."

我遇到了“mysql\u num\u rows()期望参数1是资源,给定布尔值”的问题

我意识到这意味着查询失败了。但是,我首先要做一个检查,看看查询是否成功,如果成功,我就会得到这个错误。如果查询失败,我不知道为什么我会首先进入if??我还尝试了回显查询并粘贴到phpmyadmin中,它成功运行了

代码如下:

$checkloginEmp = "CALL login('".$Email."','".$Password."', '".$NotificationID."', '".$Token."', @numRowsParam, @userIDParam);";
                //echo $checkloginEmp;

                if ($check = mysql_query($checkloginEmp)){
                    //echo $check;

                    if(mysql_num_rows($check) == 1) {
                       //retrieve info. issue points to here
                       $status= 'OK';
                       $message= null;
                    }
                    else{
                       $status= 'Not OK';
                       $message= "Invalid email/pass combination";
                    }
                 }

问题中的代码似乎试图从存储过程返回结果集

(如果该过程没有返回结果集,那么我们就没有理由使用
mysql\u num\u rows

为了从过程返回结果集,必须通过调用
mysql\u connect
时的
CLIENT\u flags
参数启用
CLIENT\u MULTI\u STATEMENTS
选项。该选项由标志值
65536
启用

如果没有该选项,就不可能从存储过程返回结果集

警告:

打开一个启用多个语句的连接将为那些易受攻击的应用程序打开一扇通向SQL注入的大门


注:

是否需要从存储过程返回结果集?是否需要返回多行,或者是否可以使用
OUT
过程参数返回标量值

正如我在前面的评论中所指出的,这段代码使用的是一个不推荐使用的接口。新开发应使用mysqliPDO

在SQL文本中加入潜在的不安全值会使应用程序易受SQL注入的攻击


编辑

Q:@spencer7593将参数绑定到存储过程不安全?你能举个例子说明攻击是如何成功的吗

A:那是另一个问题

示例代码不是“绑定参数””。它将PHP变量的值合并到SQL语句的文本中。(在代码示例中,我们没有看到这些值是否已正确转义。在没有看到这些值的情况下,我假设它们没有正确转义,因为这是我们看到的最常见的模式;因为这是更安全的假设。我们假设这些值是不安全的,直到证明它们不是

对于攻击向量和利用SQL注入的示例,我推荐OWASP项目

如果启用允许运行多个语句的选项(如果要从存储过程返回resultset,则需要使用该选项),下面是一个我们可能尝试为
$Token
传递的值示例

fee', @fi, @fo); DROP TABLE users; --

请,它们不再被维护和学习,而是考虑使用PDO,你使用的是<代码> MySqLy连接,正确,而不是<代码> MySqLII< <代码>或PDO。我必须问。你根本不应该检查<代码> MySqLyError < /Cord>。任何地方,你应该使用<代码> MySqLI< /COD>或<代码>。PDO。你为什么要花时间使用一个不推荐的接口开发应用程序,而你却可以花时间使用一个受支持的接口?这让人难以置信。你为什么要编写一个明显易受SQL注入攻击的应用程序?你应该使用一个带有绑定占位符的预处理语句。啊,不用担心;谢谢。不确定这是否有帮助,但请尝试将错误报告添加到文件的顶部在你打开PHP标签之后,例如
@Fred ii-没有区别首先,非常感谢你的详细回复!从现在开始,我一定会使用mysqli。现在我被mysql困住了。我用phpmyadmin'routines'创建了我的存储过程,所以存储过程中有一些参数。唯一的一点是我在最初的问题中漏掉的是,我确实在任何发布的变量周围使用mysql_real_escape_字符串。我尝试了你提供的注入攻击的示例,但它不起作用。这是否意味着我是安全的?使用
mysql_real_escape_string
主要防止最容易被利用的漏洞:在val中包含引号字符ue。(我说主要是防止,因为如果发生字符集翻译,引号字符仍然有可能偷偷通过。也就是说,可能有一些扩展字符“通过”逃逸字符串检查,但后来在一个字符集翻译发生时被映射到一个引用。使用<代码> MySQL LealOracle逃逸字符串势在必行。这样做就关闭了一个大范围的攻击向量。但是它并没有关闭所有的路径。再次,我推荐OWASP项目作为起点。这不是穷尽的,但它覆盖了T。每个开发人员都应该知道的最小值。并且应该让您理解为什么应该使用带绑定占位符的预处理语句。如果您的存储过程没有返回结果集(也就是说,它没有运行纯
SELECT
),那么您就不想使用
mysql_num_rows
,因为该函数只对resultset对象有意义。存储过程确实会返回一个结果集,即用户登录时的所有配置文件信息。如果我提供了正确的凭据,则会返回结果集,但如果我提供了错误的密码,则会返回上述错误