Php PDO是否关心占位符查询是否使用非关联数组?
我的应用程序中有一个查询,如下所示:Php PDO是否关心占位符查询是否使用非关联数组?,php,mysql,pdo,prepared-statement,Php,Mysql,Pdo,Prepared Statement,我的应用程序中有一个查询,如下所示: $stmt = db::db()->prepare('INSERT INTO t(a,b) VALUES :a,:b)'); $stmt->execute(array(1,2)); 后来,我遇到了一个不相关的错误,当我回顾这个脚本时,我问自己为什么它以前能工作。我本以为我应该用 $stmt->execute(array('a'=>1,'b'=>2)); 但是,它似乎有效吗 在占位符是数组键而不是问号的情况下,可以将非关联数组
$stmt = db::db()->prepare('INSERT INTO t(a,b) VALUES :a,:b)');
$stmt->execute(array(1,2));
后来,我遇到了一个不相关的错误,当我回顾这个脚本时,我问自己为什么它以前能工作。我本以为我应该用
$stmt->execute(array('a'=>1,'b'=>2));
但是,它似乎有效吗
在占位符是数组键而不是问号的情况下,可以将非关联数组与准备好的语句一起使用吗
并不是说我会参加这个练习,但这让我感到困惑,我只需要知道
谢谢是的,PDO确实很关心,在这种情况下,prepare不会失败,因为客户端会向数据库服务器发送部分查询, 此查询必须完全减去数据,以便进行预处理。 然后,客户机发送一次或多次数据,然后服务器使用数据执行预处理的查询 但是,执行时应引发以下异常:
{ "HY093", "Invalid parameter number" }
如果您阅读execute函数的PDO源代码,您将看到引发此错误的以下代码段:
if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(Z_ARRVAL_P(input_params),
¶m.name, &str_length, &num_index, 0, NULL)) {
/* yes this is correct. we don't want to count the null byte. ask wez */
param.namelen = str_length - 1;
param.paramno = -1;
} else {
/* we're okay to be zero based here */
if (num_index < 0) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY093", NULL TSRMLS_CC);
RETURN_FALSE;
}
param.paramno = num_index;
}
@ArtisticPhoenix让我完全惊讶的是,它似乎在任何一种情况下都起作用。我认为它只在执行绑定时起作用,即名称(显然在这种情况下它不是数组)。否则,它将接受命令,并退回到?占位符类型,可能有效,但如果它们的顺序不正确,则会出现问题。@ArtisiticPhoenix。我想是的。这太出乎意料了,我想我的代码一定被修改了,因为它以前不可能工作。哦,好吧。。。至少我知道。我从不使用?和方式进行查询,现在也很少编写实际的查询,主要是使用ORM.Hm。那是PDO的代码吗?因此,您需要删除一个数组定义。
/* {{{ proto bool PDOStatement::execute([array $bound_input_params])
Execute a prepared statement, optionally binding parameters */
static PHP_METHOD(PDOStatement, execute)
{
zval *input_params = NULL;
int ret = 1;
PHP_STMT_GET_OBJ;
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &input_params)) {
RETURN_FALSE;
}
PDO_STMT_CLEAR_ERR();
if (input_params) {
struct pdo_bound_param_data param;
zval **tmp;
uint str_length;
ulong num_index;
if (stmt->bound_params) {
zend_hash_destroy(stmt->bound_params);
FREE_HASHTABLE(stmt->bound_params);
stmt->bound_params = NULL;
}
zend_hash_internal_pointer_reset(Z_ARRVAL_P(input_params));
while (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(input_params), (void*)&tmp)) {
memset(¶m, 0, sizeof(param));
if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(Z_ARRVAL_P(input_params),
¶m.name, &str_length, &num_index, 0, NULL)) {
/* yes this is correct. we don't want to count the null byte. ask wez */
param.namelen = str_length - 1;
param.paramno = -1;
} else {
/* we're okay to be zero based here */
if (num_index < 0) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY093", NULL TSRMLS_CC);
RETURN_FALSE;
}
param.paramno = num_index;
}
param.param_type = PDO_PARAM_STR;
MAKE_STD_ZVAL(param.parameter);
MAKE_COPY_ZVAL(tmp, param.parameter);
if (!really_register_bound_param(¶m, stmt, 1 TSRMLS_CC)) {
if (param.parameter) {
zval_ptr_dtor(¶m.parameter);
}
RETURN_FALSE;
}
zend_hash_move_forward(Z_ARRVAL_P(input_params));
}
}
if (PDO_PLACEHOLDER_NONE == stmt->supports_placeholders) {
/* handle the emulated parameter binding,
* stmt->active_query_string holds the query with binds expanded and
* quoted.
*/
ret = pdo_parse_params(stmt, stmt->query_string, stmt->query_stringlen,
&stmt->active_query_string, &stmt->active_query_stringlen TSRMLS_CC);
if (ret == 0) {
/* no changes were made */
stmt->active_query_string = stmt->query_string;
stmt->active_query_stringlen = stmt->query_stringlen;
ret = 1;
} else if (ret == -1) {
/* something broke */
PDO_HANDLE_STMT_ERR();
RETURN_FALSE;
}
} else if (!dispatch_param_event(stmt, PDO_PARAM_EVT_EXEC_PRE TSRMLS_CC)) {
PDO_HANDLE_STMT_ERR();
RETURN_FALSE;
}
if (stmt->methods->executer(stmt TSRMLS_CC)) {
if (stmt->active_query_string && stmt->active_query_string != stmt->query_string) {
efree(stmt->active_query_string);
}
stmt->active_query_string = NULL;
if (!stmt->executed) {
/* this is the first execute */
if (stmt->dbh->alloc_own_columns && !stmt->columns) {
/* for "big boy" drivers, we need to allocate memory to fetch
* the results into, so lets do that now */
ret = pdo_stmt_describe_columns(stmt TSRMLS_CC);
}
stmt->executed = 1;
}
if (ret && !dispatch_param_event(stmt, PDO_PARAM_EVT_EXEC_POST TSRMLS_CC)) {
RETURN_FALSE;
}
RETURN_BOOL(ret);
}
if (stmt->active_query_string && stmt->active_query_string != stmt->query_string) {
efree(stmt->active_query_string);
}
stmt->active_query_string = NULL;
PDO_HANDLE_STMT_ERR();
RETURN_FALSE;
}
/* }}} */