V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
haiyang416
V2EX  ›  PHP

遇到一个 PDO 的问题,请大家帮忙测试一下这个脚本,我测试了好几个版本都有问题。

  •  
  •   haiyang416 · 2015-08-22 14:01:57 +08:00 · 2426 次点击
    这是一个创建于 3414 天前的主题,其中的信息可能已经有所发展或是发生改变。

    只要修改一下用户名和密码就可以了。

    https://gist.github.com/zither/fbcb8d86b21da51eb9af

    第 1 条附言  ·  2015-08-22 16:40:25 +08:00
    这里的问题是指即使将 email 绑定为 false ,仍然可以查询到用户。
    第 2 条附言  ·  2015-08-22 16:50:34 +08:00
    比如我的执行结果:
    第 3 条附言  ·  2015-08-23 10:49:05 +08:00

    原来是我误会了 PDO ,这个并不是它的问题。 MySQL 执行的查询语句是:

    SELECT * FROM `user` WHERE `email` = FALSE LIMIT 1;
    

    原因可以参考: http://stackoverflow.com/questions/8369379/can-false-match-some-string-in-mysql

    14 条回复    2015-08-23 10:50:48 +08:00
    laoyuan
        1
    laoyuan  
       2015-08-22 14:15:22 +08:00
    反正我用 CI 框架的时候看到社区里都说用 MySQLi , PDO 各种坑
    haiyang416
        2
    haiyang416  
    OP
       2015-08-22 14:23:45 +08:00
    @laoyuan 我刚测试了一下生成环境,也能查询到用户,先去修改下。
    luxin88
        3
    luxin88  
       2015-08-22 14:50:40 +08:00
    @laoyuan 我之前公司项目一直用 pdo ,很好用啊,最主要是他的抛错很好用
    luxin88
        4
    luxin88  
       2015-08-22 15:15:14 +08:00
    gist 的证书被 tg 劫持了?
    haiyang416
        5
    haiyang416  
    OP
       2015-08-22 15:28:21 +08:00
    @luxin88 我这里没有。
    laoyuan
        6
    laoyuan  
       2015-08-22 15:45:12 +08:00   ❤️ 1
    @luxin88 我自己用 PDO 也挺好的,就是用 CI 框架的时候踩坑了,具体什么坑我已经忘记了。。
    cevincheung
        7
    cevincheung  
       2015-08-22 15:50:21 +08:00
    用 mysqli 的路过
    zjqzxc
        8
    zjqzxc  
       2015-08-22 15:59:57 +08:00
    然而并没有发现任何问题。
    楼主是什么问题?
    话说这个 SET time_zone = '+00:00';是要闹什么。。
    haiyang416
        9
    haiyang416  
    OP
       2015-08-22 16:39:45 +08:00
    @zjqzxc 时区无所谓啊,导出的时候自带的,没改,我指的问题是上面的脚本可以查询到用户,
    我将 email 绑定为 false ,还是可以查询到。
    你的没有问题,请问 PDO 版本是?
    msg7086
        10
    msg7086  
       2015-08-23 01:14:35 +08:00   ❤️ 1
    提供一个 debug 的思路。可以把 mysql 收到的 sql 打到日志里。看看到底哪里错了。

    https://dev.mysql.com/doc/refman/5.6/en/query-log.html
    realpg
        11
    realpg  
       2015-08-23 09:28:31 +08:00   ❤️ 1
    我很少自己手动用 PDO ,基本都是用 MYSQLi ,所以没遇到楼主问题
    我仔细看了一下 PDO 的 bind 的几个方法的手册,没看到楼主这种绑定为 false 的用法,所以我想问一下楼主这种用法有没有可靠的出处?
    因为至少我用的 5.5 版里, MYSQL 并没有原生的 BOOLEAN 的类型, BOOLEAN 的类型就是个 tinyint (1 ), 0 为 false ,其他为 true 。首先你指定了传进去的变量强制类型 PDO::PARAM_BOOL 这个常量的调用,我在我庞大的参与过的 MYSQL 的项目库的代码里搜索都没见过有人用,然后把一个要代入生成 SQL 语句的参数传入一个表示否定的 false ,在没有手册详细说这种用法的前提下,这个 false 到底会被怎么解释?这个变量舍弃?还是传入这个变量是空?还是代入一个 0 ?所以我觉得得到任何乱七八糟的结果都不奇怪。

    然后就是你到底是啥需求?想取出 email 是空的?那正常的 SQL 语句你设想的是啥样的?
    select * from table where email = NULL ?这个应该用
    PDO_PARAM_NULL ,传入 NULL 处理
    还是想要找为空字符串的(非 NULL )?那就传入一个空字符串 ""


    然后是调试建议:
    1.
    $query->bindParam (1, $email, PDO::PARAM_BOOL );
    这个绑定改成
    $debug=$query->bindParam (1, $email, PDO::PARAM_BOOL );
    然后输出一下这个$debug 确认绑定操作是否返回 true ,这个绑定是否生效存疑

    2. 使用 debugDumpParams 输出一下 stmt 的情况
    http://php.net/manual/zh/pdostatement.debugdumpparams.php
    zjqzxc
        12
    zjqzxc  
       2015-08-23 09:35:33 +08:00   ❤️ 1
    昨天没认真看程序,直接执行出结果了。。
    select * from user where email=false;
    这句话想要表达什么
    email=false , false 已经告诉它是 bool 型了,我理解的是忽略 email 这个字段。(我也不知道怎么解释了)
    如果想判断空值可以用 is null
    select * from user where email is null;
    haiyang416
        13
    haiyang416  
    OP
       2015-08-23 10:41:00 +08:00
    @realpg @zjqzxc 这里只是问题还原而已,我自己肯定不会去绑定 false ,是使用 ORM 的时候偶然发现的。在查询之前会用 filter 对一些数据过滤, false 是过滤后的结果,至于绑定 bool 则是 ORM 自动判断类型的操作。事实上是我误会了 PDO ,这个并非是 PDO 的问题。
    haiyang416
        14
    haiyang416  
    OP
       2015-08-23 10:50:48 +08:00
    原因找到了,又是类型的自动转换,谢谢回复的各位,结帖。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3216 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 13:04 · PVG 21:04 · LAX 05:04 · JFK 08:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.