为什么我的PDO语句 - >执行返回false?

som*_*ent 3 php pdo execute prepare

经过无休止的测试不同方面,我已经确定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;
}
Run Code Online (Sandbox Code Playgroud)

一致地回声调试'prepared''table true''字段true''value true''flag = false'告诉我准备和绑定工作,但执行没有,$ result为空,函数返回null.

我可能忽略了一些非常明显的东西,而且我已经完全准备好让我的头完全羞愧了.先感谢您...

UPDATE

啊,连接 - 我今天的朋友.工作代码如下:

$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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

Asa*_*aph 8

如果您有一个如下所示的参数化查询:

SELECT * FROM :table WHERE :field = :value
Run Code Online (Sandbox Code Playgroud)

并且你用:table,替换值:field,和:value,你得到类似于以下的东西(实际上这是一个过度复制,但说明了这一点):

SELECT * FROM 'sometable' WHERE 'somefield' = 'somevalue'
Run Code Online (Sandbox Code Playgroud)

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

  • 太棒了Asaph - 修复了它.很容易改变它以连接`$ table`和`$ field`,并绑定`$ value` (2认同)