我有一个带有图像上传和文本输入的表单。它不断用 NULL 替换
profile_picture
字段。因此,我正在尝试创建一个动态更新查询,其中如果一个值为空,则将其完全排除在查询之外。
如有任何帮助,我们将不胜感激。
图片上传:
if (!empty($_FILES['profile_picture']) && $_FILES['profile_picture']['error'] == UPLOAD_ERR_OK) {
// Rename the uploaded file
$uploadName = $_FILES['profile_picture']['name'];
$tmp_name = $_FILES['profile_picture']['tmp_file'];
$ext = strtolower(substr($uploadName, strripos($uploadName, '.')+1));
$filename = round(microtime(true)).mt_rand().'.'.$ext;
if (move_uploaded_file($_FILES['profile_picture']['tmp_name'],'../profile_picutres/'. $filename)) {
}
}
更新查询:
$stmt = $dbh->prepare("UPDATE 001_user_table_as SET profile_picture=:profile_picture, first_name=:first_name, last_name=:last_name, phone_number=:phone_number, nationality=:nationality, years_experience=:years_experience, data=:data WHERE id=:id");
$stmt->bindParam(':profile_picture', $filename);
$stmt->bindParam(':first_name', $first_name);
$stmt->bindParam(':last_name', $last_name);
$stmt->bindParam(':phone_number', $phone_number);
$stmt->bindParam(':nationality', $nationality);
$stmt->bindParam(':years_experience', $years_experience);
$stmt->bindParam(':data', $cv_data);
$stmt->bindParam(':id', $user_id);
if($stmt->execute()){
$response["message"] = 'success';
}else{
$response["message"] = 'error';
$errors++;
}
下面是解决方案,其中输入为空,它将使用
$_POST
数组中该字段中的现有数据。
请注意,此代码只会更新非空的值。如果您想允许空值,请删除
&& strlen($_POST[$key] === 0)
部分。
// the list of allowed field names
$allowed = ["profile_picture","first_name","last_name", "phone_number", "nationality", "years_experience", "data" ];
// initialize an array with values:
$params = [];
// initialize a string with `fieldname` = :placeholder pairs
$setStr = "";
// loop over source data array
foreach ($allowed as $key)
{
if (isset($_POST[$key]) && strlen($_POST[$key] === 0))
{
$setStr .= "`$key` = :$key ,";
$params[$key] = $_POST[$key];
}
}
$setStr = rtrim($setStr, ",");
$params['id'] = $_SESSION['user_id'];
$dbh->prepare("UPDATE 001_user_table_as SET $setStr WHERE id = :id")->execute($params);
您可以使用函数来生成仅依赖于表名、允许的列和提供的列的 SQL 字符串,而不是依赖全局变量。这使您可以对任何请求来源(表单、原始正文……)做出反应。
<?php
function getPreparedUpdateSql(string $table, array $allowedColumns, array $columns): string
{
$set = [];
foreach ($columns as $column) {
if (!in_array($column, $allowedColumns)) {
continue;
}
$set[] = "$column = :$column";
}
$set = implode(", ", $set);
return "UPDATE $table SET $set WHERE id = :id";
}
这里是在您需要的任何地方使用该函数的示例。
<?php
$connection = new PDO("mysql:dbname=dbname;host=127.0.0.1", "user", "pass");
$jsonRequestBody = json_decode(file_get_contents("php://input"), true);
// ["firstname" => "firstname", "lastname" => "lastname"]
$entityId = 1;
$table = "users";
$allowedColumns = ["firstname", "lastname", "email", "role"];
$columns = array_keys($jsonRequestBody);
// ["firstname", "lastname"]
$sql = getPreparedUpdateSql($table, $allowedColumns, $columns);
// UPDATE users SET firstname = :firstname, lastname = :lastname WHERE id = :id
$query = $connection->prepare($sql);
$query->execute([...$jsonRequestBody, "id" => $entityId]);
如果你想在传统形式上使用它,你可以简单地将
columns
变量更改为此。
<?php
$columns = array_keys($_POST);
不要忘记检查是否抛出异常!