我正试图修复这段被屠杀的代码——正如你可能已经猜到的,我正在设置绑定参数语法。事实上,我甚至不确定我想做什么是可能的。这是类方法。。。
/***
*
* @select values from table
*
* @access public
*
* @param string $table The name of the table
*
* @param array $fieldlist Fields to return in results, defaults null
*
* @param array $criteria Search criteria by keyed by fieldname
*
* @param int $limit Limit of records to return, defaults 10
*
* @return Array on success or throw PDOException on failure
*
*/
public function dbSearch($table, $fieldList = null, $criteria = null, $limit = 10)
{
// setup $this->db to point to a PDO instance
$this->conn();
// build fieldlist
if( is_null($fieldList) OR !is_array($fieldList) OR count($fieldList) == 0) {
$returnFields = '*';
} else {
$returnFields = "'".implode("', '", $fieldList)."'";
}
// build criteria
if( is_null($criteria) OR !is_array($criteria) OR count($criteria) == 0) {
$whereClause = '';
} else {
$whereClause = array();
foreach ($criteria as $key => $value){
$bind_name = 'bind_'.$key; //generate a name for bind1, bind2, bind3...
$$bind_name = $value; //create a variable with this name with value in it
$bind_names[] = & $$bind_name; //put a link to this variable in array
$whereClause[] = "'$key' = :$bind_name";
}
$whereClause = count($whereClause) > 0 ? ' WHERE '.implode( ' AND ' , $whereClause ) : '';
}
$sql = "SELECT $returnFields FROM '$table' $whereClause LIMIT $limit";
$stmt = $this->db->prepare($sql);
if( $whereClause != '') {
call_user_func_array(array(&$stmt, 'bindParam'), $bind_names);
}
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
在某种程度上,我想称之为使用类似的东西。。。
// look for users in database...
$user_recs = $crud->dbSearch('user', array('user_name'), array('user_name'=> $_POST['username']));
$users = $user_recs->fetchAll(PDO::FETCH_ASSOC);
这有多疯狂?有可能吗?我是否也需要以某种方式传入参数类型?感谢您的帮助!
实际上,问题是使用绑定参数而不是绑定值。。。doh!
给定SQL语句和关联数组中的一些值,例如
$sql = "SELECT * FROM event
WHERE eventdate >= :from
AND eventdate <= :until
AND ( user_name LIKE :st OR site_name LIKE :st )
ORDER BY eventdate, start_time LIMIT 100";
$values = array( 'st' => '%'.$searchterm.'%',
'from' => $fromdate,
'until' => $untildate, );
然后这个类方法(但它可以很容易地通过一个简单的函数)完成了任务:
public function dbBoundQuery($sql, $values, $types = false) {
$this->conn();
$stmt = $this->db->prepare($sql);
foreach($values as $key => $value) {
if($types) {
$stmt->bindValue(":$key",$value,$types[$key]);
} else {
if(is_int($value)) { $param = PDO::PARAM_INT; }
elseif(is_bool($value)) { $param = PDO::PARAM_BOOL; }
elseif(is_null($value)) { $param = PDO::PARAM_NULL; }
elseif(is_string($value)) { $param = PDO::PARAM_STR; }
else { $param = FALSE;}
if($param) $stmt->bindValue(":$key",$value,$param);
}
}
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
希望这能帮助其他人。
我真的不明白这个功能怎么比传统的更好
$stmt = $db->prepare("SELECT user_name FROM user WHERE user_name = ?");
$stmt->execute($_POST['username']);
$users = $stmt->fetchAll();
请注意,
- 它使查询保持灵活性。
LIMIT ?,?
是可能的 - 它使查询保持可读性。SQL几乎是自然的英语。您仍然可以判断您的查询是做什么的,而不需要学习一些破坏大脑的语言。作为副作用,任何其他开发人员也可以理解此代码
好吧,代码中有很多地方可能会出错。
这一次,我在WHERE
子句之间没有看到任何AND
/OR
,这可能就是它不起作用的原因。
其次,它不允许您使用SQL函数。假设您需要编写这样的查询:
SELECT * FROM `table` WHERE UNIX_TIMESTAMP(date_added) < ...;
你明白了。
我建议要么使用现有的ORM(条令、推进等),要么坚持PDO。
下面是一个如何将PDO用于User类的示例:
class User
{
protected $data;
public function __get($key) {
return $this->data[$key];
}
public function __set($key, $value) {
$this->data[$key] = $value;
}
/**
* @param $value
* @param $field
* @return $this
*/
public function loadBy($value, $field)
{
$db = DbFactory::getInstance();
$query = "SELECT * FROM users WHERE $field = :$field LIMIT 1";
$stmt = $db->prepare($query);
$stmt->execute(array(":$field" => $value));
$result = $stmt->fetch();
foreach ($result as $key => $value) {
$this->$key = $value;
}
return $this;
}
}
你可以为你的实体创建这样的函数,这样你就会拥有专业化的、高效的、易于测试的函数。
PS:忽略具有名为data
的字段时出现的问题:)