SQLSTATE [HY093]:无效的参数编号:参数未定义(PDO)
我知道:这已经完成了死亡。但是,相信我,我一直在研究如何解决这个问题。我想要实现的是PDO MySQL数据库封装器,可以与PDO一起使用,我可以将它们合并到我的代码中。我的主要问题来自两个函数,特别是我试图达到的参数的实际绑定。之所以我说两个的功能与一个是相反的,尽管我努力了,但我一直无法发现哪个人正在尝试这个问题。变量的我已经确认它不是变量,这是别的。不过,事实上,我得到这个错误首先意味着东西必须是错误的代码。SQLSTATE [HY093]:无效的参数编号:参数未定义(PDO)
附录A:fetch($table, $columns, $whereArgs)
此功能的目的是简单地读取行。这是通过接受要提取的行的表,以及为了完成特定任务而需要的任何列和where子句来实现的。一旦参数被提交,一个或两个循环被调用,动态地形成查询。
public function fetch($table, $columns, $whereArgs)
{
if ($whereArgs === NULL && $columns === NULL) return false;
$select = "SELECT ";
$where = " WHERE ";
$iQuery = 0;
$sqlParams = array();
$columnCount = count($columns) - 1;
foreach($whereArgs as $key => $value)
{
$paramKey = sprintf(':%s', $key);
$where .= sprintf("`%s`= %s", $key, $paramKey);
$sqlParams[ "{$paramKey}" ] = sprintf("%s", $value);
if ($iQuery <= $columnCount)
{
$select .= sprintf('`%s`', $columns[ $iQuery ]);
$select .= ', ';
}
else
{
$select .= ' ';
}
++$iQuery;
}
if ($iQuery <= $columnCount)
{
for(; $iQuery < $columnCount; ++$iQuery)
{
if ($iQuery < $columnCount)
{
$select .= sprintf('`%s`', $columns[ $iQuery ]);
$select .= ', ';
}
else
{
$select .= ' ';
}
}
}
$select .= sprintf("FROM `%s`", $table);
$query = $select . $where;
return $this->doQuery($query, $sqlParams, TRUE, QueryType::Row);
}
附件B:doQuery($query, $sqlParams, $return = FALSE, $queryType = QueryType::None)
这个功能比较简单:它是所有绑定值和执行语句,并及时检查哪种类型的返回(返回类型,它们要么'row','column'或'all',由类QueryType
指定,该类不在本期范围内),然后返回所要求的内容。
protected function doQuery($query, $sqlParams, $return = FALSE, $queryType = QueryType::None)
{
$statement = $this->mConnection->prepare($query);
foreach($sqlParams as $param => $value)
{
$statement->bindValue($param, $value);
}
$statement->execute();
if ($return)
{
switch($queryType)
{
case QueryType::Row:
return $statement->fetch();
case QueryType::Column:
return $statement->fetchColumn();
case QueryType::All:
return $statement->fetchAll();
case QueryType::None:
return $statement;
default:
return false;
}
}
}
附件C:test.php
这仅仅是一个小的测试脚本,我写的测试数据库。
$database = new Database('evolve_admin');
$res = $database->fetch(
'evol_users',
array('user.id', 'user.email', 'user.firstname'),
array('user.email' => '[email protected]')
);
var_dump($res);
其他意见
我了解到,有是有毛病我的代码,我只是失去了,究竟它可能是。就我的调试技巧而言,我已经有研究过这个问题了很多,看来这个错误很常见。我的主要目标是让包装工作,如果有人发现代码本身有任何问题(包括特别是这个问题之外的问题),请告诉我。
对于任何人谁提供在这一个手:非常感谢你。
我想你忘却一些场所有:
$where .= sprintf("`%s`= %s", $key, $paramKey);
您使用的$wher
变量下一次是当你把它添加到$select
之一。
如果不止一个其中arg的地方是:
WHERE `%s`= %s`%s`= %s`%s`= %s`%s`= %s`%s`= %s
你没有与你的SELECT一代的思想做了错误。 顺便说一句,你有两个相同的循环和测试你的选择代if ($iQuery <= $columnCount)
。一个在where循环和另一个在外面。有什么用?
编辑:当然,我忘了指出为什么你有这个该死的错误: 它在
$sqlParams[ "{$paramKey}" ] = sprintf("%s", $value);
您创建一个表,将看起来像:array ("{:akey}" => "avalue")
(我认为值作为字符串。 你为什么使用大括号({}),它完全地更改密钥名称(应为:keyname
不{:keyname
}
编辑2: 心情好所以这里曾是你取方法的简化版本(。没有测试,但应该做工精细)
/*
* $whereArgs default value is an array, so you can call a select
* without an empty array supplied if you does not have some where clause arguments
* The separator is how the element will be binded alltogether in the where clause
*/
public function fetch($table, $columns, $whereArgs = array(), $separator= 'AND')
{
/* We return false, if the columns variable is not set, or is not an array,
* or (if it is an array) does not contain anything
* or the $whereArgs is not and array (it would mean something bad have been given)
*/
if (false == isset($columns) || false == is_array($columns)
|| 0 == count($columns) || false == is_array($whereArgs))
{
return false;
}
$select = "SELECT";
$from = " FROM `$table`";
$where = " WHERE ";
/* SELECT generation */
for ($columIt = 0; $columIt < count($columns); $columIt++)
{
$select .= " " . $columns[$columIt];
// We check if we need to add a ','
if ($columIt+1 < count($columns))
{
$select .= ",";
}
}
/* WHERE clause generation */
$sqlParams = array();
$whereIt = 0;
foreach($whereArgs as $key => $value)
{
$stripedKey = preg_replace('/\\./', '_', $key);
$where .= " $key= :$stripedKey";
$sqlParams[ ":$stripedKey" ] = "$value";
// We check if we need to add a where separator
if ($whereIt +1 < count($whereArgs))
{
$select .= " $separator";
}
$whereIt++;
}
/* the generated where clause is only printed if $whereArgs
* is not an empty array
*/
$query = $select . $from . ((0<count($whereArgs))?$where:"");
return $this->doQuery($query, $sqlParams, TRUE, QueryType::Row);
}
编辑3: '' BTW没有看到你的测试样品,但PARAM名不能包含字符
编辑4: 没看到你要跟解决它,我添加了一个pre_replace来替换子集中的'。'。 也摆脱“`”字符呼应键时,查询将失败,否则
`user.email`=:arg
不招人喜欢=)
user.email=:arg or user.`email`=:arg
首选(`)用于包括在特殊字符列名称与以前一样使用,列名称与任何现有名称都不匹配。
编辑5: 而不是剥离您的密钥来创建您的参数和参数数组。你可以使用一个安全的方式是什么,以防止误导characheters的幽灵,通过采取$的优势whereIt计数器:
$where .= " $key= :arg_$whereIt";
$sqlParams[ ":arg_$whereIt" ] = "$value";
问候
编辑后添加为什么你有这个错误(忘记告诉xD) – grifos 2012-04-01 04:16:58
是的,我欣赏帮助,但不幸的是,我仍然有我的var_dump()输出相同的确切查询: SELECT'user.id', 'user.email','user.firstname',FROM'evol_users' WHERE'user.email' =:user.email。 – zeboidlund 2012-04-01 04:23:14
什么返回var_dump或$ sqlParams? – grifos 2012-04-01 04:28:41
的问题是由于这样的事实,每一个专栏中,我曾在我的测试数据库有一个'。'在'用户'和列的名称之间。我通过用下划线替换每个句点来解决问题,并且摆脱了错误。虽然由于某种原因查询仍然无法正常工作,但我相信事情会很好。
所以,例如:
user.email
= user_email
。
根据绑定参数的数量检查生成的SQL,然后找出数字不匹配的原因。 – Corbin 2012-04-01 03:59:32
问题是只有一个参数被绑定。我测试了通过并绑定参数的for循环。我也能够输出变量,它们看起来应该完全一样。 – zeboidlund 2012-04-01 04:25:02
不,问题是没有参数被绑定(或者更具体地说,你有N个参数并且绑定了一些x使得x
Corbin
2012-04-01 04:26:46