Подготовленный отчет PHP UPDATE
Привет, я пытаюсь изучить правильный способ использования подготовленных инструкций, чтобы избежать инъекций SQL и т.д.
Когда я выполняю script, я получаю сообщение от моего script, говорящего, что 0 Rows Inserted, я ожидаю, что это скажет 1 Rows Inserted и, конечно же, обновит таблицу. Я не совсем уверен в своем подготовленном заявлении, поскольку я провел некоторое исследование, и я имею в виду, что он варьируется от примера к примеру.
Когда я обновляю свою таблицу, мне нужно объявить все поля или нормально обновлять одно поле?
Любая информация будет очень полезна.
index.php
<div id="status"></div>
<div id="maincontent">
<?php //get data from database.
require("classes/class.Scripts.inc");
$insert = new Scripts();
$insert->read();
$insert->update();?>
<form action="index2.php" enctype="multipart/form-data" method="post" name="update" id="update">
<textarea name="content" id="content" class="detail" spellcheck="true" placeholder="Insert article here"></textarea>
<input type="submit" id="update" name="update" value="update" />
</div>
классы/class.Scripts.inc
public function update() {
if (isset($_POST['update'])) {
$stmt = $this->mysqli->prepare("UPDATE datadump SET content=? WHERE id=?");
$id = 1;
/* Bind our params */
$stmt->bind_param('is', $id, $content);
/* Set our params */
$content = isset($_POST['content']) ? $this->mysqli->real_escape_string($_POST['content']) : '';
/* Execute the prepared Statement */
$stmt->execute();
printf("%d Row inserted.\n", $stmt->affected_rows);
}
}
Ответы
Ответ 1
$stmt = $this->mysqli->prepare("UPDATE datadump SET content=? WHERE id=?");
/* BK: always check whether the prepare() succeeded */
if ($stmt === false) {
trigger_error($this->mysqli->error, E_USER_ERROR);
return;
}
$id = 1;
/* Bind our params */
/* BK: variables must be bound in the same order as the params in your SQL.
* Some people prefer PDO because it supports named parameter. */
$stmt->bind_param('si', $content, $id);
/* Set our params */
/* BK: No need to use escaping when using parameters, in fact, you must not,
* because you'll get literal '\' characters in your content. */
$content = $_POST['content'] ?: '';
/* Execute the prepared Statement */
$status = $stmt->execute();
/* BK: always check whether the execute() succeeded */
if ($status === false) {
trigger_error($stmt->error, E_USER_ERROR);
}
printf("%d Row inserted.\n", $stmt->affected_rows);
На ваши вопросы:
Я получаю сообщение от моего script, говорящего, что 0 Rows Inserted
Это связано с тем, что вы изменили порядок параметров, когда вы их связали. Итак, вы ищете столбец id для числового значения вашего $content, который, вероятно, интерпретируется как 0. Таким образом, предложение UPDATE WHERE соответствует нулевым строкам.
Мне нужно объявить все поля или нормально обновлять одно поле?
Хорошо, чтобы установить только один столбец в инструкции UPDATE. Другие столбцы не будут изменены.
Ответ 2
Фактически, подготовленные заявления не так сложны, как все думают. Совсем наоборот, готовый код на основе инструкций является самым простым и аккуратным способом выполнения запроса. Возьмите, например, ваш код.
public function update($content, $id) {
$stmt = $this->mysqli->prepare("UPDATE datadump SET content=? WHERE id=?");
$stmt->bind_param('si', $content, $id);
$stmt->execute();
return $stmt->affected_rows;
}
Как вы можете видеть, код может быть очень простым и кратким при правильном использовании!
Вам нужны только три строки:
- Подготовьте запрос с помощью заполнителей
- Затем привяжите переменные (сначала установите для них правильные типы, где "i" обозначает целое число, "s" для строки и т.д.)
- И затем выполните запрос.
Проще, чем 1-2-3!
Обратите внимание, что вместо проверки каждого результата функции вручную вы можете установить режим отчетности для mysqli один раз для всех. Для этого добавьте следующую строку до mysqli_connect()
/new mysqli
:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
результат будет почти таким же, как с trigger_error, но без отдельной строки кода!
Ответ 3
<?php
if(isset($_POST["update-perfil"])){
$nombre_usuario = $_POST['nombre'];
$apellido = $_POST['apellido'];
$usser = $_POST['usuario'];
$correo = $_POST['correo'];
$fecha_nacimiento = $_POST['fecha_nacimiento'];
$dni = $_POST['dni_usuario'];
$sobremi = $_POST['sobremi'];
$pais = $_POST['pais'];
$provincia = $_POST['provincia'];
$ciudad = $_POST['ciudad'];
$idioma_principal = $_POST['idioma_principal'];
$idioma_secundario = $_POST['idioma_secundario'];
$sexo = $_POST['sexo'];
$password = $_POST['password'];
$opciones = array(
'cost' => 12
);
$password_hashed = password_hash($password, PASSWORD_BCRYPT, $opciones);
$comprobar = mysqli_num_rows(mysqli_query("SELECT usuario FROM usuarios WHERE usuario = '$usuario_session' AND id_usuario != '$id_usuario'"));
if($comprobar != 0){
echo "El nombre de usuario ya esta en uso, por favor escoja otro!";
}else{
$sql="UPDATE usuarios set usuario = ?, nombre_usaurio = ?, apellido_usuario = ?, has_pass = ?, correo = ?, fecha_nacimiento = ?, dni_usuario = ?, sobre_usuario = ?, pais_usuario = ?, provincia_usuario = ?, ciudad_usuario = ?, idioma_principal_usuario = ?, idioma_secundario_usuario = ?, sexo_usuario = ? WHERE id_usuario = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('ssssssssssssssi', $usser,$nombre_usuario, $apellido, $password, $correo, $fecha_nacimiento, $dni, $sobremi, $pais, $provincia, $ciudad, $idioma_principal, $idioma_secundario, $sexo, $id_usuario);
$stmt->execute();
if($sql){
echo "<script type='text/javascript'>windows.location='perfil.php?id_usuario=$id_usuario';</script>";
}else{
echo "no se a podido actualizar su perfil, si el problema persiste comuniquese con el <a href='soporte'>soporte</a>!";
}}
$stmt->close();
$conn->close();
}
?>