这应该很容易。。。但我想不通。如果以下execute语句在插入查询结束时有效。。。。。
$query->execute(array($this->visible_password,
$this->hashed_password,
$this->temp_hashed_password,
$this->first_name,
$this->last_name,
$this->position,
$this->location,
$this->city,
$this->email,
$this->country,
$this->institution,
$this->interests,
$this->profile_comment));
和
$result = join(", ", array_values($place_holder));
echo $result;
给出
$this->visible_password,$this->hashed_password、$this-->temp_hashed_passwords、$this->电子邮件、$this->first_name、$this_>last_name、$this->职位、$this-c>location、$thic->city、$thic_>country、$thist->institution、$thi-c>interest、$this/c>profile_ecomment
那为什么不起作用。。。。。
$query->execute(array($result))
占位符上的var_dump给出。。。
array(13) {
[0]=> string(26) "$this->visible_password"
[1]=> string(25) "$this->hashed_password"
[2]=> string(30) "$this->temp_hashed_password"
[3]=> string(15) "$this->email"
[4]=> string(20) "$this->first_name"
[5]=> string(19) "$this->last_name"
[6]=> string(18) "$this->position"
[7]=> string(18) "$this->location"
[8]=> string(14) "$this->city"
[9]=> string(17) "$this->country"
[10]=> string(21) "$this->institution"
[11]=> string(19) "$this->interests"
[12]=> string(25) "$this->profile_comment" }
$placeholder是一个数组。。。采用类的属性($attributes)
$place_holder = array();
foreach ($attributes as $key => $value) {
$place_holder[] = "$this->" . $key;
}
我一直在尝试将用户类中的create用户方法抽象化,这样我就可以在所有类中使用它。我一直在把我的网站从mysqli转换成PDO(噩梦)。这是方法。。。。
public function pdo_create_test() {
$attributes = $this->attributes();
$att = array_keys($attributes);
$question_marks = array();
foreach ($attributes as $key => $value) {
$question_marks[] = "?";
}
$place_holder = array();
foreach ($attributes as $key => $value) {
$place_holder[] = "$this->" . $key;
}
$result = join(", ", array_values($place_holder));
$sql = "INSERT INTO ".self::$table_name." (";
$sql .= join(", ", array_keys($attributes));
$sql .= ") VALUES (";
$sql .= join(", ", array_values($question_marks));
$sql .= ")";
$query = $handler->prepare($sql);
$query->execute(array($this->visible_password,
$this->hashed_password,
$this->temp_hashed_password,
$this->first_name,
$this->last_name,
$this->position,
$this->location,
$this->city,
$this->email,
$this->country,
$this->institution,
$this->interests,
$this->profile_comment));
}
以下是最新消息。。。。(我修改了占位符以获得Bill下面所说的值)我也在回显sql和占位符的结果,看看是怎么说的。
public function pdo_create_test() {
global $handler;
$attributes = $this->attributes();
$att = array_keys($attributes);
$question_marks = array();
foreach ($attributes as $key => $value) {
$question_marks[] = "?";
}
$place_holder = array();
foreach ($attributes as $key => $value) {
$place_holder[] = $this->$key;
}
$result = join(", ", array_values($place_holder));
$sql = "INSERT INTO ".self::$table_name." (";
$sql .= join(", ", array_keys($attributes));
$sql .= ") VALUES (";
$sql .= join(", ", array_values($question_marks));
$sql .= ")";
echo $sql;
echo "<br/>";
echo "<br/>";
echo $result;
$query = $handler->prepare($sql);
$query->execute(array($result));
}
对于
$user = new User;
$user->visible_password = "Sam";
$user->hashed_password = "Walsh";
$user->pdo_create_test();
输出是
插入用户(可见密码、散列密码、临时散列密码、电子邮件、名字、姓氏、职位、地点、城市、国家/地区、机构、兴趣、个人资料注释)值(
Sam,Walsh,,,,
但没有进入数据库。。。。不明白为什么。。。其他DB字段设置为NULL,所以这不是问题。。。。
PHP确实有变量的概念,所以你可以这样做:
$varname = 'foo';
$foo = 123;
echo $$varname;
但是这个功能是有限的。不能将它应用于数组的所有元素,也不能将它与对象变量的$this->foo
表示法一起使用。
您可以使用变量变量语法来获得与属性对应的对象变量的值,方法如下:
$place_holder = array();
foreach ($attributes as $key => $value) {
$place_holder[] = $this->$key;
}
注意->
之后的$key
。通常,对象变量语法在该位置没有$
。通过在那里使用$
,我告诉它获取对象变量的值,该变量的名称就是$key
的值。
顺便说一句,这里有一种更简洁(可能更快)的方法来做同样的事情:
$place_holder = array_intersect_key($attributes, get_object_vars($this));
回复您的评论:
首先,你做错了:
$result = join(", ", array_values($place_holder));
这将生成一个值由逗号分隔的字符串。如果用array($result)
包装它也没关系,它只会创建一个由单个字符串组成的数组,即使单个字符串包含逗号。
换句话说,这两个阵列非常不同:
array('A,B,C') // array with one element
array('A', 'B', 'C') // array with three elements
相反,您需要将元素数量与?
占位符数量相同的数组传递给execute()
。
所以只要通过这个:
$query->execute($place_holder);
其次,您需要在每次prepare()
或execute()
:之后检查错误
if (($query = $handler->prepare(...)) === false) {
print_r($handler->errorInfo());
}
if ($query->execute($result) === false) {
print_r($query->errorInfo());
}
或者,如果这看起来编码太多,你可以启用PDO异常,错误会导致你的应用程序以错误终止。
$handler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
我不确定place_holder
变量包含什么,但我认为这可能是原因。Join只是返回字符串的内爆函数的另一个名称。执行需要实际的物理输入项。
从PHP站点执行输入值数组:
具有与绑定参数一样多的元素的值数组在正在执行的SQL语句中。所有值均视为PDO::PARAM_STR。
更新
正如注释中所述,这里有一个函数,它将使用给定的数据对象执行SQL字符串。最好将其分为几个函数(创建参数数组、绑定参数等),但为了可读性,我将它们都放在了一个函数中。
该函数的一个示例使用可以是executeQuery('SELECT * FROM users WHERE id = :id', array('id' => 1));
function executeQuery($sql, $data) {
//Assumed that $pdo is created and is a valid PDO object
$params = array();
preg_match_all('/:'w+/', $sql, $matches);
//Loop through all the matches
//Create an array that looks like: array(
// :id => 1,
// :name => 'Me'
//)
foreach($matches[0] as $param) {
$paramName = substr($param, 1);
//If the item is not supplied in the data object, null will be used
$params[$param] = isset($data[$paramName]) && !empty($data[$paramName]) ? $data[$paramName] : null;
}
//Pepare the SQL statement
if(($stmt = $pdo->prepare($sql)) !== false) {
//Bind all parameters
foreach($params as $param => $value) {
$stmt->bindValue($param, $value);
}
//Execute the statement
$stmt->execute();
}
}