我有以下PHP代码在表格中进行非常简单的选择。
$statement = $db->prepare("SELECT * FROM account WHERE fbid = :fbid");
$statement->bindParam(":fbid",$uid, PDO::PARAM_STR,45);
$out = $statement->execute();
print_r($out) // 1;
//$out = $statement->execute(array(':fbid' => $uid)); // also doesn't work
$row = $statement->fetch();
$out
为真(成功)但$row
为空。
编辑:
$statement->debugDumpParams();
输出
SQL: [40] SELECT * FROM account WHERE fbid = :fbid Params: 1 Key: Name: [5] :fbid paramno=-1 name=[5] ":fbid" is_param=1 param_type=2
如果我按如下方式修改代码:
$statement = $db->prepare("SELECT * FROM account WHERE fbid = $uid");
$out = $statement->execute();
$row = $statement->fetch();
$row
包含我期待的记录。
我很茫然。我正在使用PDO :: prepare(),bindParams()等来防止SQL注入(可能我错了)。
编辑: 在我的例子中,$ uid是一个数字字符串(即只包含数字的字符串)。在数据库中,列类型为VARCHAR(45)
编辑:
如果我将数据库类型从VARCHAR(45)更改为BIGINT,则两个查询都有效。如果我再次将数据库类型中的类型更改回VARCHAR(45),则可以正常工作。那是什么给出了什么?
请停下来。
答案 0 :(得分:1)
您需要检查您的fbid值。它应该总是字符串,如果它的整数值大于2 ^ 32(无符号),简单地由(字符串)转换$ uid不起作用,而sprintf(“%。0f”,...)仅在整数值时起作用小于2 ^ 52,因为在32位操作系统上,当一个数字大于2 ^ 31(32无符号)PHP将假设它是双重类型而默认精确只有14位小数但fbid是20。
你必须保持fbid在PHP中只包含[0-9]的字符串,无论它在MySQL中存储为BIGINT或VARCHAR,MySQL只接受字符串sql语句并始终以字符串格式返回结果。
$mi = new mysqli("localhost", "root", "xxx", "test");
$uid = "12379739851403943597"; // Works
//$uid = 12379739851403943597; // never Works
//$uid = (string) 12379739851403943597; // get "1.2379739851404E+19" wrong string !
//$suid = sprintf("%.0f", $uid); // get "12379739851403943936" lost precise
$stmt = $mi->prepare("select * from bitest where id = ?");
$stmt->bind_param('s', $uid);
$stmt->execute();
$stmt->bind_result($id, $name);
$stmt->store_result();
print "numrow: " . $stmt->num_rows . " - \n";
$stmt->fetch();
print "$id - $name \n";
$stmt->free_result();
$stmt->close();
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', 'xxx');
$sql = "select * from bitest where id = ?";
$sth = $pdo->prepare($sql);
$sth->bindParam(1, $uid, PDO::PARAM_STR);
$sth->execute();
var_dump($sth->fetchAll(PDO::FETCH_ASSOC));
答案 1 :(得分:0)
已经有一段时间了......尝试将哈希值传递给execute:
$statement->execute(array( 'fbid' => $uid ));
答案 2 :(得分:0)
尝试删除额外参数
$statement->bindParam (":fbid", $uid, PDO::PARAM_STR);
(适用编辑)强>
你100%肯定UID周围没有额外的空白吗?使用trim()
进行测试并按值传递:
$statement->bindValue (":fbid", trim($uid), PDO::PARAM_STR);
答案 3 :(得分:0)
也许尝试PDO :: PARAM_INT
除此之外,请记住bindParam()将变量作为引用。也许您的演示代码不会显示在调用execute()之前更改该变量的值。如果需要,请参阅bindValue()。
答案 4 :(得分:0)
我认为您的PDO安装可能存在问题。
$uid = 552192373; // my facebook uid for testing
$statement = $db->prepare("SELECT * FROM users WHERE facebook_uid = :fbid");
$statement->bindParam(":fbid",$uid, PDO::PARAM_STR,45);
$out = $statement->execute();
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo '<pre>';
print_r($row);
echo '</pre>';
返回:
Array
(
[id] => 1
[facebook_name] => Jason Boehm
[facebook_uid] => 552192373
)