尝试让一个函数能够为任何表创建带有多个参数的简单 CRUD“选择”。我认为我已经完成了最难的部分,但现在无法获取数据。也许我做错了一些我无法弄清楚的事情。
我准备好的语句函数:
function prepared_query($mysqli, $sql, $params, $types = ""){
$types = $types ?: str_repeat("s", count($params));
if($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param($types, ...$params);
$stmt->execute();
return $stmt;
} else {
$error = $mysqli->errno . ' ' . $mysqli->error;
error_log($error);
}
}
查询创建者:
function create_select_query($table, $condition = "", $sort = "", $order = " ASC ", $clause = ""){
$table = escape_mysql_identifier($table);
$query = "SELECT * FROM ".$table;
if(!empty($condition)){
$query .= create_select_query_where($condition,$clause);
}
if(!empty($sort)){
$query .= " ORDER BY ".$sort." $order";
}
return $query;
}
用于创建 WHERE 子句的辅助函数:
function create_select_query_where($condition,$clause){
$query = " WHERE ";
if(is_array($condition)){
$pair = array();
$size = count($condition);
$i = 0;
if($size > 1){
foreach($condition as $field => $val){
$i++;
if($size-1 == $i){
$query .= $val." = ? ".$clause. " ";
}else{
$query .= $val." = ? ";
}
}
}else{
foreach($condition as $field => $val){
$query .= $val." = ? ";
}
}
}else if(is_string($condition)){
$query .= $condition;
}else{
$query = "";
}
return $query;
}
选择函数本身:
function crud_select($conn, $table, $args, $sort, $order, $clause){
$sql = create_select_query($table, array_keys($args),$sort, $order, $clause);
print_r($sql);
if($stmt = prepared_query($conn, $sql, array_values($args))){
return $stmt;
}else{
$errors [] = "Something weird happened...";
}
}
当我创建查询时,它似乎没问题,但无法获取数据。如果我创建一个只有一个参数的数组,则查询将转换为:
SELECT * FROM `teste_table` WHERE id = ?
如果我使用多个参数创建,它会变成这样:
SELECT * FROM `teste_table` WHERE id = ? AND username = ?
那么,我怎样才能正确地从 select 中获取数据呢?这应该用于多种目的,因此我可以获得多个结果,因此我猜最好的方法是以数组形式获取数据。
我想我已经很接近了,但无法弄清楚。谢谢
最佳答案
在 PHP >= 8.2 中,有一个函数可以让您一次性执行 SELECT 查询(以及任何其他类型的查询),execute_query() :
$query = 'SELECT Name, District FROM City WHERE CountryCode=? ORDER BY Name LIMIT ?';
$rows = $mysqli->execute_query($query, ['DEU', 5])->fetch_all(MYSQLI_ASSOC);
对于旧版本,您将需要这样的辅助函数:
function prepared_query($mysqli, $sql, $params, $types = ""){
$types = $types ?: str_repeat("s", count($params));
$stmt = $mysqli->prepare($sql)) {
$stmt->bind_param($types, ...$params);
$stmt->execute();
return $stmt;
}
只要坚持下去,它就会为你服务。
$sql = "SELECT * FROM `teste_table` WHERE id = ? AND username = ?";
$stmt = prepared_query($mysqli, $sql, [$id, $name]);
$row = $stmt->get_result()->fetch_assoc();
但是,对于真正的 CRUD,您可以使用称为“表网关模式”的方法。为此,您可以创建一个类,它将实现表上所有基本操作的方法:
- 创建记录(使用 INSERT 查询)
- 读取记录(使用主键查找)
- 更新记录
- 删除记录
然后您将为所使用的每个表扩展此类。
然后您将拥有一个简洁、可读且安全的 CRUD 解决方案。
这是一个sample Table Gateway我是为了这个场合而写的
通过简单地扩展基本类,您可以通过更简单的代码获得您想要的一切:
// add a class for the table, listing its name and columns explicitly
class UserGateway extends BasicTableGateway {
protected $table = 'gw_users';
protected $fields = ['email', 'password', 'name', 'birthday'];
}
// and then use it in your code
$userGateway = new UserGateway($pdo);
$user = $userGateway->read($id);
echo "Read: ". json_encode($user),PHP_EOL;
看 - 它非常简单,但安全且明确。
请记住,对于更复杂的查询,您必须使用纯 SQL 或向 UserGateway 类添加新方法,例如
public function getByEmail($email) {
return $this->getBySQL("SELECT * from `{$this->table}` WHERE email=?",[$email]);
}
就你目前的方法而言,它根本无法使用。我told you将您的选择功能限制为简单的主键查找。现在你打开了一 jar 蠕虫。结果,您将得到纠缠的实现代码和不可读的应用程序代码。
$table, $args, $sort, $order, $clause
所有这些变量的用途是什么?你将如何调用这个函数——一个随机顺序的乱码 SQL stub 列表,而不是简单的 SQL 字符串?以及如何指定要选择的列列表?如何使用连接? SQL 函数?别名? 为什么你不能立即编写一条 SQL 语句?你已经有了一个用于选择的函数,尽管没有向其中添加这个野蛮的错误报告代码:
关于php mysqli 准备语句选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57891243/