编辑:标题中不允许有"问题"一词。Q标记的意思是"问号">
编辑2:意识到我应该从虚拟客户记录中删除我的个人联系信息
我正在尝试制作一些基本功能来减少最近项目的维护。其中包括以下简单函数,因此我可以在以后向数据库添加列,而无需更改更新查询:
function update( $table, $fields ) {
global $db; // A slightly modified PDO object
if( count( $fields ) > 0 ) {
$query = "UPDATE `" . $table . "` SET ";
foreach( $customer as $key => $value ) {
$query .= "`" . $key . "` = ?, ";
}
$query = substr( $query, 0, -2 );
$query .= " WHERE `id` = " . $_REQUEST['id'];
$db->prepare( $query );
$db->execute( $fields );
} else { return true; }
}
当我传递一两个字段时,这个函数正在工作,但是当我尝试传递更多字段时,它失败了。这是我收到的查询、$fields
值和错误:
查询:
string 'UPDATE `customers` SET `5v` = ?, `contactaddress` = ?, `contactaddress2` = ?, `contactcity` = ?, `contactemail` = ?, `contactname` = ?, `contactphone` = ?, `contactstate` = ?, `contactzip` = ?, `corrugated` = ?, `name` = ?, `permalok` = ?, `residential` = ?, `secureseam` = ?, `tax` = ? WHERE `id` = 1' (length=301)
$fields:
array
'5v' => string '120' (length=3)
'contactaddress' => string '999 Street Dr' (length=13)
'contactaddress2' => string 'Apt 2' (length=7)
'contactcity' => string 'City' (length=9)
'contactemail' => string 'steven.abarnett@gmail.com' (length=25)
'contactname' => string 'Steven Barnett' (length=14)
'contactphone' => string '(555) 555-5555' (length=14)
'contactstate' => string 'KY' (length=2)
'contactzip' => string '55555' (length=5)
'corrugated' => string '90' (length=2)
'name' => string 'Steven's Metals' (length=15)
'permalok' => string '130' (length=3)
'residential' => string '100' (length=3)
'secureseam' => string '130' (length=3)
'tax' => string '6' (length=1)
错误:
string 'Statement execution failed: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined' (length=96)
谷歌搜索此错误,听起来像是命名参数的问题,而不是问号参数。为什么我会收到此错误?
更新:
我一直在继续调试和实验并跟踪错误,我发现失败的不是语句执行,而是之后尝试获取结果。
在我修改后的PDO对象中,我的execute()
方法中有以下代码:
// Load from database
try {
$this->stmt->execute( $args );
$this->lastid = $this->dbh->lastInsertId();
$this->data = $this->stmt->fetchAll();
} catch (PDOException $e) {
$this->error = 'Statement execution failed: ' . $e->getMessage();
return false;
}
在 try{}
部分中的每一行之间放置 echo
语句表明前两行运行顺利,但第三行会引发异常。
当我调用PDOStatement::fetchAll()
时,我的查询会失败并出现一般错误,这是否有原因?
最后更新:
事实证明,PDO和Mysql已经有6年没有很好地玩了。一般的解决方案似乎是在每次调用 PDOStatement::execute()
后取消设置 PDOStatement 对象,但这对我不起作用。该问题源于MySQL一次只能打开一个游标指向记录集中的记录,因此另一个建议的解决方案是使用PDOStatement::fetchAll()
而不是PDOStatement::fetch()
OR来调用PDOStatement::closeCusor()
。同样,这对我不起作用。我的问题来自MySQL的某些安装,它将在INSERT
,UPDATE
和DELETE
查询(所有这些都不返回任何数据(期间创建一个游标,由于它指向空数据,因此无法关闭。
我的解决方案是仅在运行返回数据的查询时调用PDOStatement::fetchAll()
。我有一个用于缓存的queryhash
变量(我对PDO类所做的重大修改(,该变量设置为false
这三种查询类型(因为您需要将查询发送到数据库而不是延迟到缓存(。我只是修改了我的execute()
函数来检查这个变量,并且只有在它未设置为 false 时才调用fetchAll()
。
您应该使用索引数组而不是关联数组。
array(
'120',
'750 Shaker Dr',
'Apt 505',
'Lexington',
'steven.abarnett@gmail.com',
'Steven Barnett',
'(859) 402-7760',
'KY',
'40504',
'90',
"Steven's Metals",
'130',
'100',
'130',
'6'
)
从 PHP 5.2 开始,传递给 execute()
的数组必须与语句字符串中的数组具有相同的键。 由于您已经使用了?
,PDO期望传递给execute()
的数字索引数组而不是关联数组。 构造 $fields
数组时,只需按正确的顺序将每个值附加到该数组上,而无需指定键。 或者,将它们提取到具有 array_values()
的数字索引数组中:
$db->execute(array_values($fields));
请参阅PDOStatement::execute()
上的文档
5.2.0 来自input_parameters的密钥必须与 SQL 中声明的密钥匹配。在 PHP 5.2.0 之前,这被默默地忽略了。