[英]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.