Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/245.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php SQL查询一致地选择不匹配的行_Php_Mysql_Sql - Fatal编程技术网

Php SQL查询一致地选择不匹配的行

Php SQL查询一致地选择不匹配的行,php,mysql,sql,Php,Mysql,Sql,我正在cookie和数据库中存储md5哈希。我有一个函数,validate\u cookie(),它读取此cookie并查询数据库以查找与此哈希关联的用户 validate\u cookie()调用另一个函数get\u user\u data()来执行实际的查询。get\u user\u data()被其他一些函数和脚本调用,因此它发送的查询非常一般。下面是函数: function get_user_data($info,$password=Null,$source=Null) { if(!

我正在cookie和数据库中存储md5哈希。我有一个函数,
validate\u cookie()
,它读取此cookie并查询数据库以查找与此哈希关联的用户

validate\u cookie()
调用另一个函数
get\u user\u data()
来执行实际的查询。
get\u user\u data()
被其他一些函数和脚本调用,因此它发送的查询非常一般。下面是函数:

function get_user_data($info,$password=Null,$source=Null)
{
  if(!$source)
    {
      $query = "SELECT * FROM `users` WHERE `id` = '".mysql_real_escape_string($info)."' OR `email` = '".mysql_real_escape_string($info)."' OR `cookie`='".mysql_real_escape_string($info)."'"; //Check to see if $info matches any column
    }
  else { $query = "SELECT * FROM `users` WHERE `".mysql_real_escape_string($source)."_token` ='".mysql_real_escape_string($info)."'";} //we got a social token
  $result = mysql_query($query);

  if($result)
    {
      $row = mysql_fetch_array($result);
      if($password)
    {
      if(crypt($password, $row['password']) == $row['password']) //password matching
        {
          return $row;
        } else {return "Password does not match!";}
    }
      else { return $row; }
    } 
  else { return "Could not get result from database!";}
}
本例中的重要查询位于
if(!source){}
块内。通过
validate\u cookie()
调用
get\u user\u data()
的方式,这个查询变成了(我已经测试过它确实变成了这个):

由于
id
是一个int字段,并且
email
中的所有内容都经过验证,因此应从该查询中选择的唯一行是那些具有匹配
cookie
字段的行

但是,无论是从PHP脚本调用此查询,还是从PHPMyAdmin手动调用此查询,都将始终选择目标行和另一行:一个在其
cookie
字段中只有
NULL
的测试用例。稍微更改散列(这样它就不会匹配任何内容)仍然会选择相同的测试用例

我的查询是否有一种我不理解的错误形式?
是否有一些神秘用法允许匹配
NULL
字段?任何帮助都将不胜感激

另外,在我被告知我应该真正使用mysqli之前,是的,我知道这一点
mysql
是老板的命令。

当且仅当您确定sql语句演变为以下内容时:

select a,b,[c ...] from mytable where a='something' or b='something' [or ...]
对于a,b[…]不为空

您只应该得到一行,其中“a”或“b”不为null,并且是“某物”。 如果没有,您的数据库/系统/驱动程序或其他什么都有问题

有时“别人错了”
我很想这么说,但这是我做的一个证明(在我的例子中,php_db2有时没有结果)

特别是,如果您确定您的语句在运行时是如何演变的,如果“本机”工具(这里是mysql admin)给出了相同的-错误的-结果,那么就存在问题,不在您的范围内

如果(看起来)您的数据库/驱动程序/安装中存在错误,您可以尝试使用类似的Workaround

select from ... where (a='som' and a is not null) or (b='som' and b is not null...) and so on 
考虑使用“TODO:等待正确的db安装”之类的标记

顺便说一句:

它正在将哈希值转换为整数。你的测试ID是3。你的哈希以3开头。它使这些人平等

select cast('3b38f280e0203d7998a0d0898095ed56' as unsigned) as x
收益率为3

像这样修复它:

SELECT id, email, password, cookie,

case when `email`  = '3b38f280e0203d7998a0d0898095ed56' then 'email'
     when `id`     = '3b38f280e0203d7998a0d0898095ed56' then 'id'
     when `cookie` = '3b38f280e0203d7998a0d0898095ed56' then 'cookie'
     else 'else' end as wtf
FROM `users`
WHERE  
    cast(`id` as char) = '3b38f280e0203d7998a0d0898095ed56' or
    `email`  = '3b38f280e0203d7998a0d0898095ed56' or
    `cookie` = '3b38f280e0203d7998a0d0898095ed56' 

如果您传入一个ID=3,那么这仍然有效,测试用例对所有3个字段都有
NULL
,或者只有cookie字段?假设任何输入结果都是相同的测试用例输出,那么必须满足一个条件<代码>或要求满足您列出的3个条件之一。使用限制1,年轻的一个。您确定
$source
的值,并且它没有达到
if
语句的
else
条件吗?我不确定假定
NULL===false
是否安全。这可能不是问题所在,但更安全的做法是执行
is_null($source)
或将默认值设置为
$source=false
,如果($source==false)也执行
,那么
限制1
将只返回测试用例,因为它是先排序的。而且,这似乎是一个太多的黑客,如果相同的条件得到满足,多行开始返回,并选择了错误的一个呢?哎哟,刚刚有人登录了其他人的帐户。在这里,我这次导出了表,并取出了所有敏感信息。现在我得到了我一直在谈论的结果:哇,我读过头了“…id是一个int字段…”,我知道的所有其他数据库系统都会给出一个sql错误,比如“不能将'3b..转换为整数”等等。我很幸运,我从来没有遇到过这样的问题。用我的mySql脚本。这一个出现在我的“记住奇怪的behvior列表”中,为此我花了一分钟才弄明白。。。如果你看看问题下面的评论,我根本不相信这是DB的问题,因为它太奇怪了。我甚至从来没有问过
id
的具体值是什么。不过,sqlfiddle解决了这个问题。
SELECT id, email, password, cookie,

case when `email`  = '3b38f280e0203d7998a0d0898095ed56' then 'email'
     when `id`     = '3b38f280e0203d7998a0d0898095ed56' then 'id'
     when `cookie` = '3b38f280e0203d7998a0d0898095ed56' then 'cookie'
     else 'else' end as wtf
FROM `users`
WHERE  
    cast(`id` as char) = '3b38f280e0203d7998a0d0898095ed56' or
    `email`  = '3b38f280e0203d7998a0d0898095ed56' or
    `cookie` = '3b38f280e0203d7998a0d0898095ed56'