Som kommentarerne ovenfor antyder, er det værd at bruge forespørgselsparametre for at beskytte dig selv mod SQL-injektion.
Du bad om et eksempel på, hvordan noget ondsindet kunne gøres. Faktisk behøver det ikke engang at være ondsindet. Enhver uskyldig streng, der lovligt indeholder en apostrof, kan bryde din SQL-forespørgsel. Ondsindet SQL-injektion udnytter denne svaghed.
Svagheden rettes ved at holde dynamiske værdier adskilt fra din SQL-forespørgsel, indtil forespørgslen er parset. Vi bruger forespørgselsparameterpladsholdere i SQL-strengen og bruger derefter prepare()
at parse det, og derefter kombinere værdierne, når du execute()
den forberedte forespørgsel. På den måde forbliver det sikkert.
Sådan vil jeg skrive din funktion. Jeg antager, at jeg bruger PDO som understøtter navngivne forespørgselsparametre. Jeg anbefaler at bruge PDO i stedet for Mysqli.
function updateProfile( $vars, $userId ) {
$db = new Database();
$safeArray = [
"gradYear",
"emailAddress",
"token",
"iosToken",
"country",
"birthYear",
"userDescription",
];
// Filter $vars to include only keys that exist in $safeArray.
$data = array_intersect_keys($vars, array_flip($safeArray));
// This might result in an empty array if none of the $vars keys were valid.
if (count($data) == 0) {
trigger_error("Error: no valid columns named in: ".print_r($vars, true));
$response = ["response" => 400, "title" => "no valid fields found"];
return $response;
}
// Build list of update assignments for SET clause using query parameters.
// Remember to use back-ticks around column names, in case one conflicts with an SQL reserved keyword.
$updateAssignments = array_map(function($column) { return "`$column` = :$column"; }, array_keys($data));
$updateString = implode(",", $updateAssignments);
// Add parameter for WHERE clause to $data.
// This must be added after $data is used to build the update assignments.
$data["userIdWhere"] = $userId;
$sqlStatement = "update users set $updateString where userId = :userIdWhere";
$stmt = $db->prepare($sqlStatement);
if ($stmt === false) {
$err = $db->errorInfo();
trigger_error("Error: {$err[2]} preparing SQL query: $sqlStatement");
$response = ["response" => 500, "title" => "database error, please report it to the site administrator"];
return $response;
}
$ok = $stmt->execute($data);
if ($ok === false) {
$err = $stmt->errorInfo();
trigger_error("Error: {$err[2]} executing SQL query: $sqlStatement");
$response = ["response" => 500, "title" => "database error, please report it to the site administrator"];
return $response;
}
$response = ["response" => 200, "title" => "update successful"];
return $response;
}