简体   繁体   English

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

[英]Why does my PDO statement -> execute return false?

After near endless rounds of testing different aspects of this, I've determined that the PDO connection works (I can run a simple query and display results), I've determined that the statement is successfully preparing, and that the values are binding properly. 经过无休止的测试不同方面,我已经确定PDO连接有效(我可以运行一个简单的查询并显示结果),我已经确定该语句已成功准备,并且值正确绑定。 For some reason, the statement won't execute. 由于某种原因,该语句将不会执行。 Just to be cute, I've tried removing all bound variables and executing a static query, and that won't work either. 只是为了可爱,我已经尝试删除所有绑定变量并执行静态查询,这也无济于事。

Code: 码:

$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;
}

Consistently echos debug text of 'prepared' 'table true' 'field true' 'value true' 'flag = false' which tells me that preparing and binding work, but executing doesn't, $result is empty and the function returns null. 一致地回声调试'prepared''table true''字段true''value true''flag = false'告诉我准备和绑定工作,但执行没有,$ result为空,函数返回null。

I've probably overlooked something horrendously obvious, and I'm fully prepared to hang my head in utter n00b shame. 我可能忽略了一些非常明显的东西,而且我已经完全准备好让我的头完全羞愧了。 Thank you in advance... 先感谢您...

UPDATE UPDATE

Ahh, concatenation -- my friend today. 啊,连接 - 我今天的朋友。 Working code follows: 工作代码如下:

$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;
}

This is safe in this instance, since $table and $field are system-generated and in no way accessible via user input; 在这种情况下这是安全的,因为$table$field是系统生成的,并且无法通过用户输入访问; only $value is exposed. 只暴露$ value。

Thank you StackOverflow! 谢谢StackOverflow! You're my favorite! 你是我的最爱! :) :)

When you have a parameterized query that looks like this: 如果您有一个如下所示的参数化查询:

SELECT * FROM :table WHERE :field = :value

and you substitute values for :table , :field , and :value , you get something similar to the following (actually this is an oversimplication but illustrates the point): 并且你用以下值代替:table:field:value ,你得到类似于下面的东西(实际上这是一个过度复制但是说明了这一点):

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

because :table and :field get the same semantic treatment as :value , ie. 因为:table:field得到的语义处理方式与:value ,即。 they are treated as strings. 他们被视为字符串。 You generally cannot parameterize table names and column names with parameterized queries. 您通常无法使用参数化查询参数化表名和列名。 You'll have to rethink your approach a little. 你必须重新考虑一下你的方法。 You might consider dynamically constructing your prepared statement string so that the table and column name parts of the query are simple concatenations, rather than binding them with PDO. 您可以考虑动态构建预准备的语句字符串,以便查询的表和列名称部分是简单的连接,而不是将它们与PDO绑定。 But you must be very careful that you validate/sanitize the table and column names because PDO won't protect you from SQL injection at that level. 但是,您必须非常小心地验证/清理表和列名称,因为PDO不会保护您免受该级别的SQL注入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM