【问题标题】:Why does my PDO statement -> execute return false?为什么我的 PDO 语句 -> 执行返回 false?
【发布时间】:2011-09-19 04:41:45
【问题描述】:

在对这个问题的不同方面进行了近乎无休止的测试之后,我确定 PDO 连接有效(我可以运行一个简单的查询并显示结果),我确定该语句正在成功准备,并且值正确绑定。由于某种原因,该语句不会执行。为了可爱起见,我尝试删除所有绑定变量并执行静态查询,但这也行不通。

代码:

$dbh = new PDO( "mysql:host=localhost;dbname=".$GLOBALS['data_name'], $GLOBALS['data_user'], $GLOBALS['data_pass'] );
$dbh->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);

$sth = $dbh->prepare( "SELECT * FROM :table WHERE :field = :value" );
if( $sth != false ) TCDebug( 'prepared' );
if( $sth->bindValue( ":table", $table ) ) TCDebug( "table true" );
if( $sth->bindValue( ":field", $field ) ) TCDebug( "field true" );
if( $sth->bindValue( ":value", $value ) ) TCDebug( "value true" );
$flag = $sth->execute();

if( $flag === true ) {
    TCDebug( 'flag = true' );
} else if( $flag === false ) {
    TCDebug( 'flag = false' );
}
$result = $sth->fetchAll();

foreach( $result as $c ) TCDebugArr( $c );
TCDebug( count( $result ) );
if( count( $result ) > 0 ) {
    return $result;
} else {
    return null;
}

一致地回显'prepared''table true''field true''value true''flag = false'的调试文本,它告诉我准备和绑定工作,但执行没有,$result为空并且函数返回 null。

我可能忽略了一些非常明显的事情,而且我已经做好了完全不耻下垂的准备。提前谢谢你...

更新

啊,串联——我今天的朋友。工作代码如下:

$dbh = new PDO( "mysql:host=localhost;dbname=".$GLOBALS['data_name'], $GLOBALS['data_user'], $GLOBALS['data_pass'] );
$dbh->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);

$prepare_str = "SELECT * FROM ". $table ." WHERE ". $field ." = :value";

$sth = $dbh->prepare( $prepare_str );
if( $sth != false ) TCDebug( 'prepared' );
if( $sth->bindValue( ":value", $value ) ) TCDebug( "value true" );
$flag = $sth->execute();

if( $flag === true ) {
    TCDebug( 'flag = true' );
} else if( $flag === false ) {
    TCDebug( 'flag = false' );
}
$result = $sth->fetchAll();

foreach( $result as $c ) TCDebugArr( $c );
TCDebug( count( $result ) );
if( count( $result ) > 0 ) {
    return $result;
} else {
    return null;
}

在这种情况下这是安全的,因为$table$field 是系统生成的,无法通过用户输入访问;只暴露了 $value。

感谢 StackOverflow!你是我的最爱! :)

【问题讨论】:

    标签: php pdo execute prepare


    【解决方案1】:

    当您有如下所示的参数化查询时:

    SELECT * FROM :table WHERE :field = :value
    

    如果您将值替换为 :table:field:value,您会得到与以下内容相似的内容(实际上这是过于简单化,但说明了重点):

    SELECT * FROM 'sometable' WHERE 'somefield' = 'somevalue'
    

    因为:table:field 得到与:value 相同的语义处理,即。它们被视为字符串。您通常不能使用参数化查询来参数化表名和列名。您将不得不重新考虑您的方法。您可能会考虑动态构造您准备好的语句字符串,以便查询的表和列名部分是简单的连接,而不是使用 PDO 绑定它们。但是您必须非常小心地验证/清理表和列名称,因为 PDO 不会保护您免受该级别的 SQL 注入。

    【讨论】:

    • 所以如果我将一个字符串与:table:field 连接起来(它们对用户输入不开放,连接时应该是安全的)并替换:value,我可能在清楚吗?
    • +1 除了“视为字符串并引用”。它们实际上是作为准备好的语句的参数传递的,但出于说明目的,您的示例是正确的
    • Awesome Asaph - 修复了它。很容易将其更改为连接$table$field,并绑定$value
    • @Phil:是的。你是对的。我试图在措辞上保持谨慎,尤其是当我说“你得到的东西相似”时。但我滑倒了。我将编辑掉“并引用”部分。感谢您指出这一点。
    • @somewhatsapient:是的,你在第一条评论中提出的想法会奏效。
    猜你喜欢
    • 2022-11-20
    • 1970-01-01
    • 2015-07-13
    • 2017-12-07
    • 1970-01-01
    • 2019-09-16
    • 2013-08-16
    • 1970-01-01
    • 2021-07-06
    相关资源
    最近更新 更多