我在理解PDO和mysqli中绑定某些变量类型的意义的一部分时遇到了问题,如果在我的情况下给出的类型似乎毫无意义。在以下代码中,类型绑定(如i
或s
)将被忽略。数据库中的表行“wert_sortierung”是INT(11)。无论$val_int
是否真的是整数,如果我通过i
,s
/ PDO::PARAM_INT
或_STR
绑定它,查询总是有效,没有中断,没有错误或警告,绑定和数据库或变量本身的类型不适合。
<?
class PDOTest {
protected $pdo;
function __construct(){
$usr="usr";
$pwd="pwd";
$host="localhost";
$db="db";
$val_int="I'm a string";
$val_str="OP";
$querystring="SELECT wert_langtext FROM TB_wert WHERE wert_sortierung = ? AND wert_CD = ?";
try {
$db_info = "mysql:host=$host;dbname=$db"; // usually provided via require_once and during construction
$this->pdo = new PDO($db_info, $usr, $pwd);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$stmt = $this->pdo->prepare($querystring);
$stmt->bindValue(1,$val_int,PDO::PARAM_INT);
$stmt->bindValue(2,$val_str,PDO::PARAM_STR);
$stmt->execute();
$row_return = $stmt->fetchAll(PDO::FETCH_ASSOC);
$this->varprint($row_return);
$this->pdo = NULL;
}
catch (PDOException $ex) {
printf ('Es spricht:');
$this->printerror("Fehla! (" . $ex->getMessage() . ")");
$this->pdo = NULL;
exit();
}
printf("<br />-------<br />");
//Added for comparison
$mysqli = new mysqli($host, $usr, $pwd, $db);
$m_stmt = $mysqli->prepare($querystring);
$m_stmt->bind_param('is',$val_int, $val_str);
$m_stmt->execute();
$m_stmt->bind_result($row_return);
$m_stmt->fetch();
$this->varprint($row_return);
$m_stmt->close();
$mysqli->close();
}
private function printerror($txt) {
printf("<p><font color=\"#ff0000\">%s</font></p>\n",
htmlentities($txt));
}
private function varprint($var) {
echo "<br />";
echo "<pre>";
echo var_dump($var);
echo "</pre>";
}
}
new PDOTest();
?>
任何人都可以在推理中指出我的错误。
答案 0 :(得分:0)
实际上是Mysql的松散输入欺骗了你。
事实上,常规的Mysql查询可以接受数字值的字符串:
SELECT wert_langtext FROM TB_wert WHERE wert_sortierung = '1' AND wert_CD = '1';
虽然准备好的声明只是遵循这种行为。
然而,相反的情况并非那么无害。使用数字
寻址字符串值SELECT wert_langtext FROM TB_wert WHERE wert_sortierung = 1;
如果wert_sortierung
是字符串类型和一些意外行为,将导致无限数量的警告,例如匹配所有行。
所以,作为一般建议我建议默认使用's'。唯一的缺点是PDO的模拟准备和它can be easily worked around.
因此,要明确回答您的问题 - 准备好的语句只允许与常规查询相同的行为,不向其添加任何内容。使用预处理语句也可以通过常规查询完成所有操作。不,绑定不会验证您的数据(但它应该。我的类我测试整数占位符,如果没有给出数值,则抛出异常)