我无法在pdo update prepared语句中找到好的文档,甚至更难找到有关使用pdo预处理语句动态更新数据库的文档。我已经让我的动态插件工作但是我的更新有问题。我得到的错误是:
警告:PDOStatement :: execute()[pdostatement.execute]: SQLSTATE [HY093]:参数号无效:未定义参数 在 /Users/scottmcpherson/Sites/phpsites/projectx/application/models/db.php 第91行错误
这是我创建的类减去了几个与此问题无关的方法:
<?php
require_once("../config/main.php");
class Database{
protected static $dbFields = array('username', 'password');
public $db;
public $tableName = 'users';
public $id = 1;
public $username = "Jonny";
public $password = "Appleseed";
public function __construct() {
$this->connect();
}
public function connect(){
try {
$this->db = new PDO("mysql:host=".DB_SERVER."; dbname=".DB_NAME, DB_USER, DB_PASS);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
}
public function properties() {
$properties = array();
foreach (self::$dbFields as $field) {
if (isset($this->field) || property_exists($this, $field)) {
$properties[$field] = $this->$field;
}
}
return $properties;
}
public function propertyValues() {
$property = $this->properties();
$propertyValues = array();
foreach ($property as $key => $value) {
$propertyValues = ":" . implode(", :", array_keys($property));
}
return $propertyValues;
}
public function polishedVals(){
// The end result of this function is:
// username=:username, password=:password
$props = $this->properties();
$phaseOne = array();
foreach ($props as $key => $value) {
$phaseOne[$key] = ":".$key;
}
$phaseTwo = array();
foreach ($phaseOne as $key => $value) {
$phaseTwo[] = "{$key}={$value}";
}
$polishedVals = implode(", ", $phaseTwo);
return $polishedVals;
}
public function update(){
$stmt = "UPDATE ". $this->tableName." SET ";
$stmt .= $this->polishedVals();
$stmt .= "WHERE id=" . $this->id;
$stmt = $this->db->prepare($stmt);
if($stmt->execute($this->properties())) {
echo "yes";
} else {
echo "error ";
}
}
}
$database = new Database();
echo$database->update();
?>
将所有变量替换为实际值,我使用update()方法得到的结果如下所示:
public function update(){
$stmt = "UPDATE users SET ";
$stmt .= "username=:username, password=:password ";
$stmt .= "WHERE id=1";
$stmt = $this->db->prepare($stmt);
if($stmt->execute($this->properties())) {
echo "yes";
} else {
echo "error ";
}
}
除了发现此问题外,如果您发现此代码存在任何其他问题,请与我们联系。我仍然是PHP的新手。
编辑:我现在已经创建了一个新方法,它将:添加到属性数组中每个键的开头:
public function colProperties(){
$properties = $this->properties();
$withCols = array();
foreach($properties as $key => $value){
$withCols[":".$key] = $value;
}
return $withCols;
}
所以我的update()方法现在看起来像: public function update(){
$stmt = "UPDATE ". $this->tableName." SET ";
$stmt .= $this->polishedVals();
$stmt .= "WHERE id=" . $this->id;
$stmt = $this->db->prepare($stmt);
if($stmt->execute($this->colProperties())) {
echo "yes";
} else {
echo "error ";
}
}
如果我var_dump($ this-&gt; colProperties)我得到: array(2){[“:username”] =&gt; string(5)“Jonny”[“:password”] =&gt; string(9)“Appleseed”} 并且仍然遇到同样的错误。
答案 0 :(得分:2)
我不认为将参数传递给UPDATE查询需要的方法与SELECT方法不同。 PDOStatement->execute()手册页中的信息应适用:
<?php
/* Execute a prepared statement by passing an array of insert values */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->execute(array(':calories' => $calories, ':colour' => $colour));
?>
您正在使用命名参数,因此execute()
需要一个关联数组。使用var_dump()在$this->properties()
之前显示execute()
:
var_dump($this->properties())
确保您的密钥完全匹配。
答案 1 :(得分:0)
错误在于
之间$stmt .= $this->polishedVals();
$stmt .= "WHERE id=" . $this->id;
WHERE子句之间需要有一个空格,因为在implode之后,sortedVals()方法不会添加空格。所以,你会有像
这样的东西UPDATE User SET city=:city, location=:locationWHERE User.id=28
导致错误。 简单的错误。